Source Code Cross Referenced for InternalTriggerExecutionContext.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » sql » execute » 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 » Database DBMS » db derby 10.2 » org.apache.derby.impl.sql.execute 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.sql.execute.InternalTriggerExecutionContext
004:
005:           Licensed to the Apache Software Foundation (ASF) under one or more
006:           contributor license agreements.  See the NOTICE file distributed with
007:           this work for additional information regarding copyright ownership.
008:           The ASF licenses this file to you under the Apache License, Version 2.0
009:           (the "License"); you may not use this file except in compliance with
010:           the License.  You may obtain a copy of the License at
011:
012:              http://www.apache.org/licenses/LICENSE-2.0
013:
014:           Unless required by applicable law or agreed to in writing, software
015:           distributed under the License is distributed on an "AS IS" BASIS,
016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017:           See the License for the specific language governing permissions and
018:           limitations under the License.
019:
020:         */
021:
022:        package org.apache.derby.impl.sql.execute;
023:
024:        import org.apache.derby.iapi.services.sanity.SanityManager;
025:        import org.apache.derby.iapi.error.PublicAPI;
026:        import org.apache.derby.iapi.db.TriggerExecutionContext;
027:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
028:        import org.apache.derby.iapi.sql.ResultSet;
029:        import org.apache.derby.iapi.sql.execute.CursorResultSet;
030:        import org.apache.derby.iapi.sql.execute.ExecRow;
031:        import org.apache.derby.iapi.types.DataValueDescriptor;
032:        import org.apache.derby.iapi.sql.execute.ExecutionStmtValidator;
033:        import org.apache.derby.iapi.sql.execute.ConstantAction;
034:        import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
035:        import org.apache.derby.iapi.error.StandardException;
036:        import org.apache.derby.iapi.services.i18n.MessageService;
037:        import org.apache.derby.iapi.reference.SQLState;
038:        import org.apache.derby.iapi.jdbc.ConnectionContext;
039:        import org.apache.derby.catalog.UUID;
040:        import java.util.Enumeration;
041:        import java.util.Vector;
042:        import java.util.Hashtable;
043:        import java.sql.Connection;
044:        import java.sql.SQLException;
045:        import java.sql.Statement;
046:        import org.apache.derby.iapi.error.ExceptionSeverity;
047:
048:        /**
049:         * There is one of these beasts per INSERT/DELETE/UPDATE 
050:         * statement.  It fulfills the contract for the externally
051:         * visible trigger execution context and it validates
052:         * that a statement that is about to be executed doesn't
053:         * violate the restrictions placed upon what can be executed
054:         * from a trigger.
055:         * <p>
056:         * Note that it is crucial that cleanup() is called once
057:         * the DML has completed, cleanup() makes sure that users
058:         * can't do something invalid on a tec reference that they
059:         * were holding from when the trigger fired.
060:         *
061:         */
062:        public class InternalTriggerExecutionContext implements 
063:                TriggerExecutionContext, ExecutionStmtValidator {
064:            /*
065:             ** Immutable
066:             */
067:            protected int[] changedColIds;
068:            protected String[] changedColNames;
069:            protected int dmlType;
070:            protected String statementText;
071:            protected ConnectionContext cc;
072:            protected UUID targetTableId;
073:            protected String targetTableName;
074:            protected LanguageConnectionContext lcc;
075:
076:            /*
077:             ** Mutable
078:             */
079:            protected CursorResultSet beforeResultSet;
080:            protected CursorResultSet afterResultSet;
081:
082:            /**
083:             * used exclusively for InsertResultSets which have autoincrement 
084:             * columns.
085:             */
086:            protected ExecRow afterRow;
087:
088:            protected boolean cleanupCalled;
089:            protected TriggerEvent event;
090:            protected TriggerDescriptor triggerd;
091:
092:            /*
093:             ** Used to track all the result sets we have given out to
094:             ** users.  When the trigger context is no longer valid,
095:             ** we close all the result sets that may be in the user
096:             ** space because they can no longer provide meaningful
097:             ** results.
098:             */
099:            private Vector resultSetVector;
100:
101:            /**
102:             * aiCounters is a vector of AutoincrementCounters used to keep state which
103:             * might be used by the trigger. This is only used by Insert triggers--
104:             * Delete and Update triggers do not use this variable.
105:             * 
106:             * @see AutoincrementCounter
107:             * 
108:             */
109:            private Vector aiCounters;
110:
111:            /**
112:             * aiHT is a hashtable of autincrement <key, value> pairs. This is used for
113:             * ai values generated by the trigger.
114:             */
115:            private Hashtable aiHT;
116:
117:            /**
118:             * Build me a big old nasty trigger execution context.
119:             * Damnit.
120:             * <p>
121:             * About the only thing of real interest to outside observers
122:             * is that it pushes itself as the trigger execution context
123:             * in the lcc.  Be sure to call <i>cleanup()</i> when you
124:             * are done, or you will be flogged like the reprobate that
125:             * you are.
126:             *
127:             * @param lcc	the lcc
128:             * @param statementText	the text of the statement that caused the
129:             *		trigger to fire.  may be null if we are replicating
130:             * @param changedColIds	the list of columns that changed.  Null
131:             *		for all columns or INSERT/DELETE.
132:             * @param changedColNames	the names that correspond to changedColIds
133:             * @param targetTableId	the UUID of the table upon which the trigger
134:             *		fired
135:             * @param targetTableName	the name of the table upon which the trigger
136:             *		fired
137:             * @param aiCounters		A vector of AutoincrementCounters to keep state
138:             * 							of the ai columns in this insert trigger.a
139:             *
140:             * @exception StandardException on error
141:             */
142:            public InternalTriggerExecutionContext(
143:                    LanguageConnectionContext lcc, ConnectionContext cc,
144:                    String statementText, int dmlType, int[] changedColIds,
145:                    String[] changedColNames, UUID targetTableId,
146:                    String targetTableName, Vector aiCounters)
147:                    throws StandardException {
148:                this .dmlType = dmlType;
149:                this .changedColIds = changedColIds;
150:                this .changedColNames = changedColNames;
151:                this .statementText = statementText;
152:                this .cc = cc;
153:                this .lcc = lcc;
154:                this .targetTableId = targetTableId;
155:                this .targetTableName = targetTableName;
156:                this .resultSetVector = new Vector();
157:                this .aiCounters = aiCounters;
158:
159:                if (SanityManager.DEBUG) {
160:                    if ((changedColIds == null) != (changedColNames == null)) {
161:                        SanityManager.THROWASSERT("bad changed cols, "
162:                                + "(changedColsIds == null) = "
163:                                + (changedColIds == null)
164:                                + "  (changedColsNames == null) = "
165:                                + (changedColNames == null));
166:                    }
167:                    if (changedColIds != null) {
168:                        SanityManager.ASSERT(
169:                                changedColIds.length == changedColNames.length,
170:                                "different number of changed col ids vs names");
171:                    }
172:                }
173:
174:                lcc.pushTriggerExecutionContext(this );
175:            }
176:
177:            void setBeforeResultSet(CursorResultSet rs) {
178:                beforeResultSet = rs;
179:            }
180:
181:            void setAfterResultSet(CursorResultSet rs) throws StandardException {
182:                afterResultSet = rs;
183:
184:                if (aiCounters != null) {
185:                    if (triggerd.isRowTrigger()) {
186:                        // An after row trigger needs to see the "first" row inserted 
187:                        rs.open();
188:                        afterRow = rs.getNextRow();
189:                        rs.close();
190:                    } else {
191:                        // after statement trigger needs to look at the last value.
192:                        if (!triggerd.isBeforeTrigger())
193:                            resetAICounters(false);
194:                    }
195:                }
196:            }
197:
198:            void setCurrentTriggerEvent(TriggerEvent event) {
199:                this .event = event;
200:            }
201:
202:            void clearCurrentTriggerEvent() {
203:                event = null;
204:            }
205:
206:            void setTrigger(TriggerDescriptor triggerd) {
207:                this .triggerd = triggerd;
208:            }
209:
210:            void clearTrigger() throws StandardException {
211:                event = null;
212:                triggerd = null;
213:                if (afterResultSet != null) {
214:                    afterResultSet.close();
215:                    afterResultSet = null;
216:                }
217:                if (beforeResultSet != null) {
218:                    beforeResultSet.close();
219:                    beforeResultSet = null;
220:                }
221:            }
222:
223:            /**
224:             * Cleanup the trigger execution context.  <B>MUST</B>
225:             * be called when the caller is done with the trigger
226:             * execution context.
227:             * <p>
228:             * We go to somewhat exaggerated lengths to free up
229:             * all our resources here because a user may hold on
230:             * to a TEC after it is valid, so we clean everything
231:             * up to be on the safe side.
232:             *
233:             * @exception StandardException on unexpected error
234:             */
235:            protected void cleanup() throws StandardException {
236:                lcc.popTriggerExecutionContext(this );
237:
238:                /*
239:                 ** Explicitly close all result sets that we have
240:                 ** given out to the user.  
241:                 */
242:                for (Enumeration e = resultSetVector.elements(); e
243:                        .hasMoreElements();) {
244:                    java.sql.ResultSet rs = (java.sql.ResultSet) e
245:                            .nextElement();
246:                    try {
247:                        rs.close();
248:                    } catch (SQLException se) {
249:                    }
250:                }
251:                resultSetVector = null;
252:
253:                /*
254:                 ** We should have already closed our underlying
255:                 ** ExecResultSets by closing the jdbc result sets,
256:                 ** but in case we got an error that we caught and
257:                 ** ignored, explicitly close them.
258:                 */
259:                if (afterResultSet != null) {
260:                    afterResultSet.close();
261:                    afterResultSet = null;
262:                }
263:                if (beforeResultSet != null) {
264:                    beforeResultSet.close();
265:                    beforeResultSet = null;
266:                }
267:
268:                lcc = null;
269:                cleanupCalled = true;
270:            }
271:
272:            /**
273:             * Make sure that the user isn't trying to get a result
274:             * set after we have cleaned up. 
275:             */
276:            private void ensureProperContext() throws SQLException {
277:                if (cleanupCalled) {
278:                    throw new SQLException(
279:                            MessageService
280:                                    .getTextMessage(SQLState.LANG_STATEMENT_CLOSED_NO_REASON),
281:                            "XCL31", ExceptionSeverity.STATEMENT_SEVERITY);
282:                }
283:            }
284:
285:            /////////////////////////////////////////////////////////
286:            //
287:            // ExecutionStmtValidator
288:            //
289:            /////////////////////////////////////////////////////////
290:            /**
291:             * Make sure that whatever statement is about to be executed
292:             * is ok from the context of this trigger.
293:             * <p>
294:             * Note that we are sub classed in replication for checks
295:             * for replication specific language.
296:             *
297:             * @param constantAction the constant action of the action
298:             *	that we are to validate
299:             *
300:             * @exception StandardException on error
301:             */
302:            public void validateStatement(ConstantAction constantAction)
303:                    throws StandardException {
304:
305:                // DDL statements are not allowed in triggers. Direct use of DDL
306:                // statements in a trigger's action statement is disallowed by the
307:                // parser. However, this runtime check is needed to prevent execution
308:                // of DDL statements by procedures within a trigger context. 
309:                if (constantAction instanceof  DDLConstantAction) {
310:                    throw StandardException.newException(
311:                            SQLState.LANG_NO_DDL_IN_TRIGGER,
312:                            triggerd.getName(), constantAction.toString());
313:                }
314:
315:                // No INSERT/UPDATE/DELETE for a before trigger. There is no need to 
316:                // check this here because parser does not allow these DML statements
317:                // in a trigger's action statement in a before trigger. Parser also 
318:                // disallows creation of before triggers calling procedures that modify
319:                // SQL data.   
320:
321:            }
322:
323:            /////////////////////////////////////////////////////////
324:            //
325:            // TriggerExectionContext
326:            //
327:            /////////////////////////////////////////////////////////
328:
329:            /**
330:             * Get the target table name upon which the 
331:             * trigger event is declared.
332:             *
333:             * @return the target table
334:             */
335:            public String getTargetTableName() {
336:                return targetTableName;
337:            }
338:
339:            /**
340:             * Get the target table UUID upon which the 
341:             * trigger event is declared.
342:             *
343:             * @return the uuid of the target table
344:             */
345:            public UUID getTargetTableId() {
346:                return targetTableId;
347:            }
348:
349:            /**
350:             * Get the type for the event that caused the
351:             * trigger to fire.
352:             *
353:             * @return the event type (e.g. UPDATE_EVENT)
354:             */
355:            public int getEventType() {
356:                return dmlType;
357:            }
358:
359:            /**
360:             * Get the text of the statement that caused the
361:             * trigger to fire.
362:             *
363:             * @return the statement text
364:             */
365:            public String getEventStatementText() {
366:                return statementText;
367:            }
368:
369:            /**
370:             * Get the columns that have been modified by the statement
371:             * that caused this trigger to fire.  If all columns are
372:             * modified, will return null (e.g. for INSERT or DELETE will
373:             * return null).
374:             *
375:             * @return an array of Strings
376:             */
377:            public String[] getModifiedColumns() {
378:                return changedColNames;
379:            }
380:
381:            /**
382:             * Find out of a column was changed, by column name
383:             *
384:             * @param columnName the column to check
385:             *
386:             * @return true if the column was modified by this statement.
387:             * Note that this will always return true for INSERT
388:             * and DELETE regardless of the column name passed in.
389:             */
390:            public boolean wasColumnModified(String columnName) {
391:                if (changedColNames == null) {
392:                    return true;
393:                }
394:
395:                for (int i = 0; i < changedColNames.length; i++) {
396:                    if (changedColNames[i].equals(columnName)) {
397:                        return true;
398:                    }
399:                }
400:                return false;
401:            }
402:
403:            /**
404:             * Find out of a column was changed, by column number
405:             *
406:             * @param columnNumber the column to check
407:             *
408:             * @return true if the column was modified by this statement.
409:             * Note that this will always return true for INSERT
410:             * and DELETE regardless of the column name passed in.
411:             */
412:            public boolean wasColumnModified(int columnNumber) {
413:                if (changedColIds == null) {
414:                    return true;
415:                }
416:
417:                for (int i = 0; i < changedColNames.length; i++) {
418:                    if (changedColIds[i] == columnNumber) {
419:                        return true;
420:                    }
421:                }
422:                return false;
423:            }
424:
425:            /**
426:             * Returns a result set row the old images of the changed rows.
427:             * For a row trigger, the result set will have a single row.  For
428:             * a statement trigger, this result set has every row that has
429:             * changed or will change.  If a statement trigger does not affect 
430:             * a row, then the result set will be empty (i.e. ResultSet.next()
431:             * will return false).
432:             *
433:             * @return the ResultSet containing before images of the rows 
434:             * changed by the triggering event.
435:             *
436:             * @exception SQLException if called after the triggering event has
437:             * completed
438:             */
439:            public java.sql.ResultSet getOldRowSet() throws SQLException {
440:                ensureProperContext();
441:                if (beforeResultSet == null) {
442:                    return null;
443:                }
444:
445:                try {
446:                    CursorResultSet brs = beforeResultSet;
447:                    /* We should really shallow clone the result set, because it could be used
448:                     * at multiple places independently in trigger action.  This is a bug found
449:                     * during the fix of beetle 4373.
450:                     */
451:                    if (brs instanceof  TemporaryRowHolderResultSet)
452:                        brs = (CursorResultSet) ((TemporaryRowHolderResultSet) brs)
453:                                .clone();
454:                    else if (brs instanceof  TableScanResultSet)
455:                        brs = (CursorResultSet) ((TableScanResultSet) brs)
456:                                .clone();
457:                    brs.open();
458:                    java.sql.ResultSet rs = cc.getResultSet(brs);
459:                    resultSetVector.addElement(rs);
460:                    return rs;
461:                } catch (StandardException se) {
462:                    throw PublicAPI.wrapStandardException(se);
463:                }
464:            }
465:
466:            /**
467:             * Returns a result set row the new images of the changed rows.
468:             * For a row trigger, the result set will have a single row.  For
469:             * a statement trigger, this result set has every row that has
470:             * changed or will change.  If a statement trigger does not affect 
471:             * a row, then the result set will be empty (i.e. ResultSet.next()
472:             * will return false).
473:             *
474:             * @return the ResultSet containing after images of the rows 
475:             * changed by the triggering event.
476:             *
477:             * @exception SQLException if called after the triggering event has
478:             * completed
479:             */
480:            public java.sql.ResultSet getNewRowSet() throws SQLException {
481:                ensureProperContext();
482:
483:                if (afterResultSet == null) {
484:                    return null;
485:                }
486:                try {
487:                    /* We should really shallow clone the result set, because it could be used
488:                     * at multiple places independently in trigger action.  This is a bug found
489:                     * during the fix of beetle 4373.
490:                     */
491:                    CursorResultSet ars = afterResultSet;
492:                    if (ars instanceof  TemporaryRowHolderResultSet)
493:                        ars = (CursorResultSet) ((TemporaryRowHolderResultSet) ars)
494:                                .clone();
495:                    else if (ars instanceof  TableScanResultSet)
496:                        ars = (CursorResultSet) ((TableScanResultSet) ars)
497:                                .clone();
498:                    ars.open();
499:                    java.sql.ResultSet rs = cc.getResultSet(ars);
500:                    resultSetVector.addElement(rs);
501:                    return rs;
502:                } catch (StandardException se) {
503:                    throw PublicAPI.wrapStandardException(se);
504:                }
505:            }
506:
507:            /**
508:             * Like getBeforeResultSet(), but returns a result set positioned
509:             * on the first row of the before result set.  Used as a convenience
510:             * to get a column for a row trigger.  Equivalent to getBeforeResultSet()
511:             * followed by next().
512:             *
513:             * @return the ResultSet positioned on the old row image.
514:             *
515:             * @exception SQLException if called after the triggering event has
516:             * completed
517:             */
518:            public java.sql.ResultSet getOldRow() throws SQLException {
519:                java.sql.ResultSet rs = getOldRowSet();
520:                if (rs != null)
521:                    rs.next();
522:
523:                return rs;
524:            }
525:
526:            /**
527:             * Like getAfterResultSet(), but returns a result set positioned
528:             * on the first row of the before result set.  Used as a convenience
529:             * to get a column for a row trigger.  Equivalent to getAfterResultSet()
530:             * followed by next().
531:             *
532:             * @return the ResultSet positioned on the new row image.
533:             *
534:             * @exception SQLException if called after the triggering event has
535:             * completed
536:             */
537:            public java.sql.ResultSet getNewRow() throws SQLException {
538:                java.sql.ResultSet rs = getNewRowSet();
539:                if (rs != null)
540:                    rs.next();
541:                return rs;
542:            }
543:
544:            public Long getAutoincrementValue(String identity) {
545:                // first search the hashtable-- this represents the ai values generated
546:                // by this trigger.
547:                if (aiHT != null) {
548:                    Long value = (Long) aiHT.get(identity);
549:                    if (value != null)
550:                        return value;
551:                }
552:
553:                // If we didn't find it in the hashtable search in the counters which
554:                // represent values inherited by trigger from insert statements.
555:                if (aiCounters != null) {
556:                    for (int i = 0; i < aiCounters.size(); i++) {
557:                        AutoincrementCounter aic = (AutoincrementCounter) aiCounters
558:                                .elementAt(i);
559:
560:                        //				System.out.println("in itec:getaivalue " + aic);
561:                        if (identity.equals(aic.getIdentity())) {
562:                            //					System.out.println("in itec:getvalue--returning " +  aic.getCurrentValue());
563:                            return aic.getCurrentValue();
564:                        }
565:                    }
566:                }
567:
568:                // didn't find it-- return NULL.
569:                return null;
570:            }
571:
572:            /**
573:             * Copy a hashtable of autoincrement values into the trigger 
574:             * execution context hashtable of autoincrement values.
575:             */
576:            public void copyHashtableToAIHT(Hashtable from) {
577:                if (from == null)
578:                    return;
579:                if (aiHT == null)
580:                    aiHT = new Hashtable();
581:                for (Enumeration e = from.keys(); e.hasMoreElements();) {
582:                    Object key = e.nextElement();
583:                    Object value = from.get(key);
584:                    aiHT.put(key, value);
585:                    //			System.out.println(" in itec:chte-- " + key + " " + value);
586:                }
587:            }
588:
589:            /** 
590:             * Reset Autoincrement counters to the beginning or the end.
591:             * 
592:             * @param		begin		if True, reset the AutoincremnetCounter to the
593:             *                          beginning-- used to reset the counters for the
594:             * 							next trigger. If false, reset it to the end--
595:             *                          this sets up the counter appropriately for a
596:             *                          AFTER STATEMENT trigger.
597:             */
598:            public void resetAICounters(boolean begin) {
599:                if (aiCounters == null)
600:                    return;
601:
602:                afterRow = null;
603:
604:                int size = aiCounters.size();
605:                for (int i = 0; i < size; i++) {
606:                    AutoincrementCounter aic = (AutoincrementCounter) aiCounters
607:                            .elementAt(i);
608:                    aic.reset(begin);
609:                }
610:            }
611:
612:            /**
613:             * Update Autoincrement Counters from the last row inserted.
614:             *
615:             */
616:            public void updateAICounters() throws StandardException {
617:                if (aiCounters == null)
618:                    return;
619:
620:                int size = aiCounters.size();
621:                for (int i = 0; i < size; i++) {
622:                    AutoincrementCounter aic = (AutoincrementCounter) aiCounters
623:                            .elementAt(i);
624:                    DataValueDescriptor dvd = afterRow.getColumn(aic
625:                            .getColumnPosition());
626:                    aic.update(dvd.getLong());
627:                }
628:            }
629:
630:            public String toString() {
631:                return triggerd.getName();
632:            }
633:
634:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.