Source Code Cross Referenced for GenericTransaction.java in  » J2EE » Dinamica » dinamica » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » Dinamica » dinamica 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package dinamica;
002:
003:        import java.util.HashMap;
004:        import javax.naming.*;
005:        import javax.servlet.http.HttpSession;
006:        import javax.sql.DataSource;
007:
008:        /**
009:         * Base class to program business transaction services (read/write).
010:         * All transactions will subclass this class.
011:         * 
012:         * <br>
013:         * Creation date: 4/10/2003<br>
014:         * Last Update: 4/10/2003<br>
015:         * (c) 2003 Martin Cordova<br>
016:         * This code is released under the LGPL license<br>
017:         * @author Martin Cordova
018:         */
019:        public class GenericTransaction extends AbstractModule {
020:
021:            /** store recordsets published by this service */
022:            private HashMap<String, Recordset> _publish = new HashMap<String, Recordset>();
023:
024:            /**
025:             * Publish recordset to be consumed by Output modules
026:             * @param key Recordset ID
027:             * @param data Recordset object
028:             */
029:            protected void publish(String key, Recordset data) throws Throwable {
030:                _publish.put(key, data);
031:
032:                /* get recordset simple metadata (recordcount, pagecount, etc) */
033:                data.setID(key);
034:                Recordset info = data.getRecordsetInfo();
035:
036:                /* publish this new recordset */
037:                String infoID = key + ".metadata";
038:                _publish.put(infoID, info);
039:
040:            }
041:
042:            /**
043:             * Transaction service - this method must be redefined
044:             * by descendants of this class, include a super.service(inputParams)
045:             * as the first line of your service() method code to reuse base
046:             * functionality (auto-creation of recordsets based on recordset elements defined in config.xml).
047:             * In this method the business logic will be contained, and results will be represented
048:             * as recordsets that will be consumed by Output objects. Recordsets are published using
049:             * the method publish(id, rsObject). This class provides a method to retrieve
050:             * a recordset using its ID and throws an error if the recordset is not present in the HashMap.<br>
051:             * If inputParams is not null then it is published with the id "_request".
052:             * @param inputParams Request parameters pre-validated and represented as a Recordset with one record.
053:             * Recordset fields are set according to the data types defined in the validator.xml file.
054:             * @return 0 if success - any other return values are user defined
055:             * @throws Throwable
056:             */
057:            public int service(Recordset inputParams) throws Throwable {
058:                int rc = createRecordsets(inputParams);
059:
060:                if (inputParams != null)
061:                    _publish.put("_request", inputParams);
062:
063:                return rc;
064:
065:            }
066:
067:            /**
068:             * Create recordsets using config.xml parameters.
069:             * For recordsets created using SQL templates, all values
070:             * from the inputParams recordset will be auto-replaced into
071:             * the template. This recordset is only created when using
072:             * a validator (validator.xml definition to auto-validate request parameters). 
073:             * @throws Throwable in case of invalid config.xml parameters or JDBC exceptions.
074:             */
075:            protected int createRecordsets(Recordset inputParams)
076:                    throws Throwable {
077:
078:                int rc = 0;
079:
080:                /* get database object */
081:                Db db = getDb();
082:
083:                /* get recordsets config */
084:                Recordset rs = _config.getRecordsets();
085:                Recordset rs1 = null;
086:
087:                /* for each defined recordset */
088:                while (rs.next()) {
089:
090:                    /* get parameters */
091:                    String id = (String) rs.getValue("id");
092:                    String source = (String) rs.getValue("source");
093:                    String scope = (String) rs.getValue("scope");
094:                    String onempty = (String) rs.getValue("onempty");
095:                    String maxRows = (String) rs.getValue("maxrows");
096:                    int limit = 0;
097:                    if (maxRows != null)
098:                        limit = Integer.parseInt(maxRows);
099:                    String dataSrc = rs.getString("datasource");
100:                    String params = rs.getString("params");
101:
102:                    /* create recordset using appropiate source */
103:                    if (source.equals("sql")) {
104:                        String sqlFile = getResource(id);
105:                        sqlFile = this .getSQL(sqlFile, inputParams);
106:
107:                        if (params != null) {
108:                            // PATCH 2005-04-05 support for alternative input parameters recordset for SQL templates
109:                            Recordset rsParams = getRecordset(params);
110:                            if (rsParams.getRecordCount() > 0)
111:                                rsParams.first();
112:                            else
113:                                throw new Throwable(
114:                                        "The recordset ["
115:                                                + params
116:                                                + "] used to replace SQL template values is empty.");
117:                            sqlFile = this .getSQL(sqlFile, rsParams);
118:                        }
119:
120:                        //PATCH 2005-03-14 support datasource defined at recordset level
121:                        if (dataSrc == null) {
122:                            if (limit > 0)
123:                                rs1 = db.get(sqlFile, limit);
124:                            else
125:                                rs1 = db.get(sqlFile);
126:                        } else {
127:                            rs1 = dbGet(dataSrc, sqlFile, limit);
128:                        }
129:
130:                        if (onempty != null) {
131:                            if (rs1.getRecordCount() == 0)
132:                                rc = Integer.parseInt(onempty);
133:                        }
134:                    } else if (source.equals("session")) {
135:                        rs1 = (Recordset) getSession().getAttribute(id);
136:                        //PATCH 2005-03-01 - enhance error message if session attribute is null
137:                        if (rs1 == null)
138:                            throw new Throwable(
139:                                    "Recordset ["
140:                                            + id
141:                                            + "] not found in Session attribute, maybe the application was reloaded, destroying the session.");
142:                    } else if (source.equals("request")) {
143:                        rs1 = (Recordset) _req.getAttribute(id);
144:                        if (rs1 == null)
145:                            throw new Throwable("Request attribute [" + id
146:                                    + "] does not contain a recordset.");
147:                    } else if (source.equals("textfile")) {
148:                        rs1 = this .getRsFromFlatFile(id);
149:                    } else if (source.equals("class")) {
150:                        IRecordsetProvider rsProv = (IRecordsetProvider) getObject(id);
151:                        rs1 = rsProv.getRecordset(inputParams);
152:                    } else {
153:                        throw new Throwable(
154:                                "Invalid recordset source in config.xml ("
155:                                        + _config.path
156:                                        + "). Source attribute values can be sql, session, textfile or request only.");
157:                    }
158:
159:                    /* publish this recordset */
160:                    _publish.put(id, rs1);
161:
162:                    /* get recordset simple metadata (recordcount, pagecount, etc) */
163:                    rs1.setID(id);
164:                    Recordset info = rs1.getRecordsetInfo();
165:
166:                    /* publish this new recordset */
167:                    String infoID = id + ".metadata";
168:                    _publish.put(infoID, info);
169:
170:                    /* persist recordset if necessary (in session or request object */
171:                    if (scope.equals("session")) {
172:                        getSession().setAttribute(id, rs1);
173:                    } else if (scope.equals("request")) {
174:                        _req.setAttribute(id, rs1);
175:                    } else if (!scope.equals("transaction")) {
176:                        throw new Throwable(
177:                                "Invalid recordset scope in config.xml ("
178:                                        + _config.path
179:                                        + "). Scope attribute values can be transaction, session or request only.");
180:                    }
181:
182:                }
183:
184:                return rc;
185:            }
186:
187:            /**
188:             * Returns a recordset published by this transaction
189:             * @param id ID or symbolic name which was used to publish the
190:             * recordset - either by code or using the config.xml elements.
191:             * @return Recordset
192:             * @throws Throwable if ID oes not match any of the IDs of the published recordsets
193:             */
194:            public Recordset getRecordset(String id) throws Throwable {
195:                if (_publish.containsKey(id)) {
196:                    return (Recordset) _publish.get(id);
197:                } else {
198:                    throw new Throwable("Invalid recordset ID: " + id);
199:                }
200:            }
201:
202:            /**
203:             * Generate SQL command. Encapsulates the use of the TemplateEngine
204:             * class, to make it easier for developers writing Transaction Modules
205:             * @param sql SQL Template
206:             * @param rs Recordset with at least one record - there must be
207:             * a current record
208:             * @return SQL command with replaced values
209:             * @throws Throwable
210:             */
211:            protected String getSQL(String sql, Recordset rs) throws Throwable {
212:
213:                TemplateEngine t = new TemplateEngine(_ctx, _req, sql);
214:
215:                //patch 2007-10-25
216:                //use custom locale for LABELS in SQL template
217:                HttpSession s = getRequest().getSession(true);
218:                java.util.Locale l = (java.util.Locale) s
219:                        .getAttribute("dinamica.user.locale");
220:                t.setLocale(l);
221:
222:                return t.getSql(rs);
223:
224:            }
225:
226:            /**
227:             * Load the appropiate class and creates an object
228:             * that MUST subclass GenericTransaction. This method is
229:             * used by Transactions that delegate work on "subtransaction"
230:             * objects. All these classes subclass GenericTransaction to inherit all the
231:             * code supporting business logic programming. You may define your
232:             * own methods in those classes, they are intended to refactor
233:             * common business code that may be used by multiple Transactions.<br>
234:             * Typically, you will use code like this:<br>
235:             * <pre>
236:             * MyOwnClass obj = (MyOwnClass)getObject("mypackage.MyOwnClass");
237:             * obj.myMethod();
238:             * </pre>
239:             * <br>
240:             * An object created this way inherits all the power of
241:             * the GenericTransaction, including the availability of
242:             * security information (current user), access to the same
243:             * database connection as the caller, etc. Both objects participate
244:             * in the same JDBC Transaction if this feature was enabled in
245:             * the config.xml file.
246:             * 
247:             * @param className Name of the class to instantiate
248:             * @return An object of class GenericTransaction
249:             * @throws Throwable
250:             */
251:            protected GenericTransaction getObject(String className)
252:                    throws Throwable {
253:
254:                GenericTransaction t = null;
255:
256:                /* load transaction class */
257:                t = (GenericTransaction) Thread.currentThread()
258:                        .getContextClassLoader().loadClass(className)
259:                        .newInstance();
260:                t.init(_ctx, _req, _res);
261:                t.setConfig(_config);
262:                t.setConnection(_conn);
263:
264:                /* log jdbc performance? */
265:                t.setLogWriter(_pw);
266:
267:                return t;
268:
269:            }
270:
271:            /**
272:             * Create a recordset with all the fields
273:             * required to produce a chart with ChartOutput. This recordset
274:             * will contain no records.
275:             * @return Recordset with the column structure required by 
276:             * the class ChartOutput
277:             * @throws Throwable
278:             */
279:            public Recordset getChartInfoRecordset() throws Throwable {
280:                /* define chart params recordset */
281:                Recordset rs = new Recordset();
282:                rs.append("chart-plugin", java.sql.Types.VARCHAR);
283:                rs.append("title", java.sql.Types.VARCHAR);
284:                rs.append("title-x", java.sql.Types.VARCHAR);
285:                rs.append("title-y", java.sql.Types.VARCHAR);
286:                rs.append("column-x", java.sql.Types.VARCHAR);
287:                rs.append("column-y", java.sql.Types.VARCHAR);
288:                rs.append("title-series", java.sql.Types.VARCHAR);
289:                rs.append("width", java.sql.Types.INTEGER);
290:                rs.append("height", java.sql.Types.INTEGER);
291:                rs.append("data", java.sql.Types.VARCHAR);
292:                rs.append("dateformat", java.sql.Types.VARCHAR);
293:
294:                //added on april-06-2004
295:                rs.append("session", java.sql.Types.VARCHAR); //true|false: save in session?
296:                rs.append("image-id", java.sql.Types.VARCHAR);//session attribute id
297:
298:                //added on july-19-2005
299:                rs.append("color", java.sql.Types.VARCHAR); //true|false: save in session?
300:
301:                return rs;
302:            }
303:
304:            /**
305:             * Return DataSource object using JNDI prefix
306:             * configured in web.xml context parameter. This is an
307:             * utility method to help simplify Transaction code. A DataSource
308:             * can be obtained with a single line of code:<br><br>
309:             * <pre>
310:             * javax.sql.DataSource ds = getDataSource("jdbc/customersDB");
311:             * setConnection(ds.getConnection);
312:             * ....
313:             * </pre>
314:             * <br>
315:             * Remember that when you use your own datasource, you
316:             * must close the connection in your Transaction code! consult
317:             * the reference guide ("Sample code" section) for more information.
318:             * 
319:             * @param name Name of the datasource (Example: jdbc/customersdb)
320:             * @return DataSource object
321:             * @throws Throwable If DataSource cannot be obtained
322:             */
323:            protected DataSource getDataSource(String name) throws Throwable {
324:
325:                //get datasource config from web.xml
326:                String jndiPrefix = "";
327:                if (getContext() != null)
328:                    jndiPrefix = getContext().getInitParameter("jndi-prefix");
329:                else
330:                    jndiPrefix = "java:comp/env/";
331:
332:                if (jndiPrefix == null)
333:                    jndiPrefix = "";
334:
335:                DataSource ds = Jndi.getDataSource(jndiPrefix + name);
336:                if (ds == null)
337:                    throw new Throwable("Can't get datasource: " + name);
338:
339:                return ds;
340:
341:            }
342:
343:            /**
344:             * Return the default application DataSource object
345:             * as configured in web.xml context parameters. This is a
346:             * utility method to help simplify Transaction code. A DataSource
347:             * can be obtained with a single line of code:<br><br>
348:             * <pre>
349:             * javax.sql.DataSource ds = getDataSource();
350:             * setConnection(ds.getConnection());
351:             * ....
352:             * </pre>
353:             * <br>
354:             * Remember that when you use your own datasource, you
355:             * must close the connection in your Transaction code! please consult
356:             * the reference guide ("Sample code" section) for more information.
357:             * 
358:             * @return DataSource object
359:             * @throws Throwable If DataSource cannot be obtained
360:             */
361:            protected DataSource getDataSource() throws Throwable {
362:
363:                //get datasource config from web.xml
364:                String jndiPrefix = null;
365:                String name = null;
366:
367:                if (getContext() != null) {
368:
369:                    if (getConfig().transDataSource != null)
370:                        name = getConfig().transDataSource;
371:                    else
372:                        name = getContext().getInitParameter("def-datasource");
373:
374:                    jndiPrefix = getContext().getInitParameter("jndi-prefix");
375:
376:                } else
377:                    throw new Throwable(
378:                            "This method can't return a datasource if servlet the context is null.");
379:
380:                if (jndiPrefix == null)
381:                    jndiPrefix = "";
382:
383:                DataSource ds = Jndi.getDataSource(jndiPrefix + name);
384:                if (ds == null)
385:                    throw new Throwable("Can't get datasource: " + name);
386:
387:                return ds;
388:
389:            }
390:
391:            /**
392:             * Returns an "env-entry" value stored in web.xml.
393:             * @param name env-entry-name element
394:             **/
395:            protected String getEnvEntry(String name) throws Throwable {
396:
397:                Context env = (Context) new InitialContext()
398:                        .lookup("java:comp/env");
399:                String v = (String) env.lookup(name);
400:                return v;
401:
402:            }
403:
404:            /**
405:             * Retrieve internal HashMap containing all published Recordsets
406:             * in case some output module needs to serialize this object
407:             * or anything else
408:             * @return HashMap containing all published Recordsets
409:             */
410:            public HashMap<String, Recordset> getData() {
411:                return _publish;
412:            }
413:
414:            /**
415:             * Utility method to retrieve a recordset from a different data source
416:             * than the one used by the action
417:             * @param DataSourceName Data Source name like "jdbc/xxxx"
418:             * @param sql SQL command that returns a result set
419:             * @param limit The maximum number of rows to retrieve (0 = no limit) 
420:             * @return
421:             * @throws Throwable
422:             */
423:            protected Recordset dbGet(String DataSourceName, String sql,
424:                    int limit) throws Throwable {
425:                java.sql.Connection conn = getDataSource(DataSourceName)
426:                        .getConnection();
427:                try {
428:                    Db db = new Db(conn);
429:
430:                    if (this ._pw != null)
431:                        db.setLogWriter(_pw);
432:
433:                    if (limit > 0)
434:                        return db.get(sql, limit);
435:                    else
436:                        return db.get(sql);
437:                } catch (Throwable e) {
438:                    throw e;
439:                } finally {
440:                    if (conn != null)
441:                        conn.close();
442:                }
443:            }
444:
445:            /**
446:             * Utility method to retrieve a recordset from a different data source
447:             * than the one used by the action
448:             * @param DataSourceName Data Source name like "jdbc/xxxx"
449:             * @param sql SQL command that returns a result set
450:             * @return
451:             * @throws Throwable
452:             */
453:            protected Recordset dbGet(String DataSourceName, String sql)
454:                    throws Throwable {
455:                return dbGet(DataSourceName, sql, 0);
456:            }
457:
458:            /**
459:             * Creates a recordset according to a structure defined in a
460:             * flat file. The 1st line defines the column types, the second line
461:             * defines the column names. From 3rd line begins data records. Columns
462:             * are separated by TAB, rows are separated by CR+NL.
463:             * @param path Path to flat file defining recordset structure and data. If path starts with "/..." it is interpreted as a location relative
464:             * to the context, otherwise it is assumed to be located in the Action's path.
465:             * @return Recordset according to the flat file structure
466:             * @throws Throwable
467:             */
468:            protected Recordset getRsFromFlatFile(String path) throws Throwable {
469:                Recordset rs = new Recordset();
470:                String data = getResource(path);
471:                String lineSep = "\r\n";
472:                if (data.indexOf(lineSep) < 0)
473:                    lineSep = "\n";
474:
475:                String rows[] = StringUtil.split(data, lineSep);
476:                String listseparator = "\t";
477:
478:                //adjust which list separator is used, tab or comma or semicolon
479:                if (rows[0].indexOf(",") != -1)
480:                    listseparator = ",";
481:                else if (rows[0].indexOf(";") != -1)
482:                    listseparator = ";";
483:
484:                String fields[] = StringUtil.split(rows[0], listseparator);
485:                String names[] = StringUtil.split(rows[1], listseparator);
486:                boolean is_blank_row = false;
487:
488:                if (fields.length != names.length)
489:                    throw new Throwable(
490:                            "Row #2 (column names) does not match the right number of columns.");
491:
492:                for (int i = 0; i < fields.length; i++) {
493:                    if (fields[i].toLowerCase().equals("varchar"))
494:                        rs.append(names[i], java.sql.Types.VARCHAR);
495:                    else if (fields[i].toLowerCase().equals("date"))
496:                        rs.append(names[i], java.sql.Types.DATE);
497:                    else if (fields[i].toLowerCase().equals("integer"))
498:                        rs.append(names[i], java.sql.Types.INTEGER);
499:                    else if (fields[i].toLowerCase().equals("double"))
500:                        rs.append(names[i], java.sql.Types.DOUBLE);
501:                    else {
502:                        throw new Throwable(
503:                                "Invalid column type ["
504:                                        + fields[i]
505:                                        + "]. Valid column types are: varchar, date, integer and double.");
506:                    }
507:
508:                }
509:
510:                for (int i = 2; i < rows.length; i++) {
511:                    //here is a empty line
512:                    if (rows[i].equals(""))
513:                        continue;
514:
515:                    //add a record if not all of last row is null,flatfile recordset does not allow all fields is null
516:                    if (!is_blank_row)
517:                        rs.addNew();
518:
519:                    //initial flag
520:                    is_blank_row = true;
521:
522:                    String value[] = StringUtil.split(rows[i], listseparator);
523:
524:                    //if (fields.length!=value.length)
525:                    //      throw new Throwable("Row #" + i + " does not match the right number of columns.");
526:
527:                    for (int j = 0; j < Math.min(fields.length, value.length); j++) {
528:                        //replace lables such as ${lbl:},${ses:},%{req:}
529:                        value[j] = getSQL(value[j], null);
530:
531:                        //if this field is null,then set field null.if all fields is null,is_blank_row will equal true.
532:                        if (value[j].equals("")
533:                                || value[j].toLowerCase().equals("null")) {
534:                            rs.setValue(names[j], null);
535:                        } else {
536:                            is_blank_row = false;
537:                            if (fields[j].toLowerCase().equals("varchar"))
538:                                rs.setValue(names[j], value[j]);
539:                            else if (fields[j].toLowerCase().equals("date")) {
540:                                if (value[j].indexOf("@") != -1) //formated date value
541:                                {
542:                                    String date[] = StringUtil.split(value[j],
543:                                            "@");
544:                                    rs.setValue(names[j], StringUtil
545:                                            .getDateObject(date[0], date[1]));
546:                                } else {
547:                                    rs.setValue(names[j], StringUtil
548:                                            .getDateObject(value[j],
549:                                                    "yyyy-MM-dd"));
550:                                }
551:                            } else if (fields[j].toLowerCase()
552:                                    .equals("integer"))
553:                                rs.setValue(names[j], new Integer(value[j]));
554:                            else if (fields[j].toLowerCase().equals("double"))
555:                                rs.setValue(names[j], new Double(value[j]));
556:                        }
557:                    }
558:                }
559:
560:                //remove the last row if all field is null
561:                if (is_blank_row)
562:                    rs.delete(rs.getRecordNumber());
563:
564:                return rs;
565:            }
566:
567:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.