Source Code Cross Referenced for BasicTransaction.java in  » Database-ORM » MMBase » org » mmbase » bridge » implementation » 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 ORM » MMBase » org.mmbase.bridge.implementation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:        This software is OSI Certified Open Source Software.
004:        OSI Certified is a certification mark of the Open Source Initiative.
005:
006:        The license (Mozilla version 1.0) can be read at the MMBase site.
007:        See http://www.MMBase.org/license
008:
009:         */
010:
011:        package org.mmbase.bridge.implementation;
012:
013:        import java.util.*;
014:        import java.io.*;
015:        import org.mmbase.bridge.*;
016:        import org.mmbase.security.UserContext;
017:        import org.mmbase.module.core.*;
018:        import org.mmbase.util.logging.*;
019:
020:        /**
021:         * The basic implementation for a Transaction cLoud.
022:         * A Transaction cloud is a cloud which buffers allc hanegs made to nodes -
023:         * which means that chanegs are committed only if you commit the transaction itself.
024:         * This mechanism allows you to rollback changes if something goes wrong.
025:         * @author Pierre van Rooden
026:         * @version $Id: BasicTransaction.java,v 1.36 2008/01/09 10:56:36 michiel Exp $
027:         */
028:        public class BasicTransaction extends BasicCloud implements  Transaction {
029:
030:            private static final Logger log = Logging
031:                    .getLoggerInstance(BasicTransaction.class);
032:            /**
033:             * The id of the transaction for use with the transaction manager.
034:             */
035:            protected String transactionContext; // not final because of deserialization
036:
037:            private boolean canceled = false;
038:            private boolean committed = false;
039:            /**
040:             * The name of the transaction as used by the user.
041:             */
042:            protected String transactionName; // not final because of deserialization
043:
044:            protected BasicCloud parentCloud; // not final because of deserialization
045:
046:            /**
047:             * @since MMBase 1.9
048:             */
049:            protected final Collection<MMObjectNode> getCoreNodes() {
050:                // if the parent cloud is itself a transaction,
051:                // do not create a new one, just use that context instead!
052:                // this allows for nesting of transactions without loosing performance
053:                // due to additional administration
054:                if (parentCloud instanceof  BasicTransaction) {
055:                    return ((BasicTransaction) parentCloud).getCoreNodes();
056:                } else {
057:                    try {
058:                        // XXX: the current transaction manager does not allow multiple transactions with the
059:                        // same name for different users
060:                        // We solved this here, but this should really be handled in the Transactionmanager.
061:                        log.debug("using transaction " + transactionContext);
062:                        Collection<MMObjectNode> cn = BasicCloudContext.transactionManager
063:                                .getTransactions().get(transactionContext);
064:                        if (cn == null) {
065:                            cn = BasicCloudContext.transactionManager
066:                                    .createTransaction(transactionContext);
067:                        }
068:                        return cn;
069:                    } catch (TransactionManagerException e) {
070:                        throw new BridgeException(e.getMessage(), e);
071:                    }
072:                }
073:            }
074:
075:            /*
076:             * Constructor to call from the CloudContext class.
077:             * Package only, so cannot be reached from a script.
078:             * @param transactionName name of the transaction (assigned by the user)
079:             * @param cloud The cloud this transaction is working on
080:             */
081:            BasicTransaction(String transactionName, BasicCloud cloud) {
082:                super (transactionName, cloud);
083:                this .transactionName = transactionName;
084:                this .parentCloud = cloud;
085:                // if the parent cloud is itself a transaction,
086:                // do not create a new one, just use that context instead!
087:                // this allows for nesting of transactions without loosing performance
088:                // due to additional administration
089:                if (parentCloud instanceof  BasicTransaction) {
090:                    transactionContext = ((BasicTransaction) parentCloud).transactionContext;
091:                } else {
092:                    // XXX: the current transaction manager does not allow multiple transactions with the
093:                    // same name for different users
094:                    // We solved this here, but this should really be handled in the Transactionmanager.
095:                    transactionContext = account + "_" + transactionName;
096:                    log.debug("using transaction " + transactionContext);
097:                    getCoreNodes(); // will call 'createTransaction
098:                }
099:            }
100:
101:            public NodeList getNodes() {
102:                return new BasicNodeList(getCoreNodes(), this );
103:            }
104:
105:            public synchronized boolean commit() {
106:                if (canceled) {
107:                    throw new BridgeException("Cannot commit transaction'"
108:                            + name + "' (" + transactionContext
109:                            + "), it was already canceled.");
110:                }
111:                if (committed) {
112:                    throw new BridgeException("Cannot commit transaction'"
113:                            + name + "' (" + transactionContext
114:                            + "), it was already committed.");
115:                }
116:                log.debug("Committing transaction " + transactionContext);
117:
118:                parentCloud.transactions.remove(transactionName); // hmpf
119:
120:                // if this is a transaction within a transaction (theoretically possible)
121:                // leave the committing to the 'parent' transaction
122:                if (parentCloud instanceof  Transaction) {
123:                    // do nothing
124:                } else {
125:                    try {
126:                        assert BasicCloudContext.transactionManager
127:                                .getTransaction(transactionContext).size() == getNodes()
128:                                .size();
129:
130:                        log.info("Commiting " + getNodes());
131:                        BasicCloudContext.transactionManager
132:                                .resolve(transactionContext);
133:                        BasicCloudContext.transactionManager.commit(
134:                                userContext, transactionContext);
135:
136:                        // This is a hack to call the commitprocessors which are only available in the bridge.
137:                        for (Node n : getNodes()) {
138:                            log.debug("Commiting " + n);
139:                            if (n == null) {
140:                                log.warn("Found null in transaction");
141:                                continue;
142:                            }
143:                            if (!n.isChanged() && !n.isNew()) {
144:                                log.debug("Ignored because not changed "
145:                                        + n.isChanged() + "/" + n.isNew());
146:                                continue;
147:                            }
148:                            if (TransactionManager.EXISTS_NOLONGER.equals(n
149:                                    .getStringValue("_exists"))) {
150:                                log.debug("Ignored because exists no longer.");
151:                                continue;
152:                            }
153:                            log.debug("Calling commit on " + n);
154:                            n.commit();
155:                        }
156:
157:                    } catch (TransactionManagerException e) {
158:                        // do we drop the transaction here or delete the trans context?
159:                        // return false;
160:                        throw new BridgeException(e.getMessage()
161:                                + " for transaction with " + getNodes(), e);
162:                    }
163:                }
164:
165:                committed = true;
166:                return true;
167:            }
168:
169:            public synchronized void cancel() {
170:                if (canceled) {
171:                    throw new BridgeException("Cannot cancel transaction'"
172:                            + name + "' (" + transactionContext
173:                            + "), it was already canceled.");
174:                }
175:                if (committed) {
176:                    throw new BridgeException("Cannot cancel transaction'"
177:                            + name + "' (" + transactionContext
178:                            + "), it was already committed.");
179:                }
180:
181:                // if this is a transaction within a transaction (theoretically possible)
182:                // call the 'parent' transaction to cancel everything
183:                if (parentCloud instanceof  Transaction) {
184:                    ((Transaction) parentCloud).cancel();
185:                } else {
186:                    try {
187:                        //   BasicCloudContext.transactionManager.cancel(account, transactionContext);
188:                        BasicCloudContext.transactionManager.cancel(
189:                                userContext, transactionContext);
190:                    } catch (TransactionManagerException e) {
191:                        // do we drop the transaction here or delete the trans context?
192:                        throw new BridgeException(e.getMessage(), e);
193:                    }
194:                }
195:                // remove the transaction from the parent cloud
196:                parentCloud.transactions.remove(transactionName);
197:                canceled = true;
198:            }
199:
200:            /*
201:             * Transaction-notification: add a new temporary node to a transaction.
202:             * @param currentObjectContext the context of the object to add
203:             */
204:            @Override
205:            void add(String currentObjectContext) {
206:                try {
207:                    BasicCloudContext.transactionManager.addNode(
208:                            transactionContext, account, currentObjectContext);
209:                } catch (TransactionManagerException e) {
210:                    throw new BridgeException(e.getMessage(), e);
211:                }
212:            }
213:
214:            /*
215:             */
216:            @Override
217:            int add(BasicNode node) {
218:                int id = node.getNumber();
219:                String currentObjectContext = BasicCloudContext.tmpObjectManager
220:                        .getObject(account, "" + id, "" + id);
221:                // store new temporary node in transaction
222:                add(currentObjectContext);
223:                node.setNode(BasicCloudContext.tmpObjectManager.getNode(
224:                        account, "" + id));
225:                //  check nodetype afterwards?
226:                return id;
227:            }
228:
229:            @Override
230:            void createAlias(BasicNode node, String aliasName) {
231:                checkAlias(aliasName);
232:                try {
233:                    String aliasContext = BasicCloudContext.tmpObjectManager
234:                            .createTmpAlias(aliasName, account, "a"
235:                                    + node.temporaryNodeId, ""
236:                                    + node.temporaryNodeId);
237:                    BasicCloudContext.transactionManager.addNode(
238:                            transactionContext, account, aliasContext);
239:                } catch (TransactionManagerException e) {
240:                    throw new BridgeException(e.getMessage(), e);
241:                }
242:            }
243:
244:            /*
245:             * Transaction-notification: remove a temporary (not yet committed) node in a transaction.
246:             * @param currentObjectContext the context of the object to remove
247:             */
248:            @Override
249:            void remove(String currentObjectContext) {
250:                try {
251:                    BasicCloudContext.transactionManager.removeNode(
252:                            transactionContext, account, currentObjectContext);
253:                } catch (TransactionManagerException e) {
254:                    throw new BridgeException(e.getMessage(), e);
255:                }
256:            }
257:
258:            @Override
259:            void remove(MMObjectNode node) {
260:                String oMmbaseId = "" + node.getValue("number");
261:                String currentObjectContext = BasicCloudContext.tmpObjectManager
262:                        .getObject(account, "" + oMmbaseId, oMmbaseId);
263:                add(currentObjectContext);
264:                delete(currentObjectContext);
265:            }
266:
267:            void delete(String currentObjectContext, MMObjectNode node) {
268:                delete(currentObjectContext);
269:            }
270:
271:            /*
272:             * Transaction-notification: remove an existing node in a transaction.
273:             * @param currentObjectContext the context of the object to remove
274:             */
275:            void delete(String currentObjectContext) {
276:                try {
277:                    BasicCloudContext.transactionManager.deleteObject(
278:                            transactionContext, account, currentObjectContext);
279:                } catch (TransactionManagerException e) {
280:                    throw new BridgeException(e.getMessage(), e);
281:                }
282:            }
283:
284:            @Override
285:            boolean contains(MMObjectNode node) {
286:                // additional check, so transaction can still get nodes after it has committed.
287:                if (transactionContext == null) {
288:                    return false;
289:                }
290:                try {
291:                    Collection<MMObjectNode> transaction = BasicCloudContext.transactionManager
292:                            .getTransaction(transactionContext);
293:                    return transaction.contains(node);
294:                } catch (TransactionManagerException tme) {
295:                    throw new BridgeException(tme.getMessage(), tme);
296:                }
297:            }
298:
299:            @Override
300:            BasicNode makeNode(MMObjectNode node, String nodeNumber) {
301:                if (committed) {
302:                    return parentCloud.makeNode(node, nodeNumber);
303:                } else {
304:                    return super .makeNode(node, nodeNumber);
305:                }
306:            }
307:
308:            /**
309:             * If this Transaction is scheduled to be garbage collected, the transaction is canceled and cleaned up.
310:             * Unless it has already been committed/canceled, ofcourse, and
311:             * unless the parentcloud of a transaction is a transaction itself.
312:             * In that case, the parent transaction should cancel!
313:             * This means that a transaction is always cleared - if it 'times out', or is not properly removed, it will
314:             * eventually be removed from the MMBase cache.
315:             */
316:            @Override
317:            protected void finalize() {
318:                if ((transactionContext != null)
319:                        && !(parentCloud instanceof  Transaction)) {
320:                    cancel();
321:                }
322:            }
323:
324:            public boolean isCanceled() {
325:                return canceled;
326:            }
327:
328:            public boolean isCommitted() {
329:                return committed;
330:            }
331:
332:            public Object getProperty(Object key) {
333:                Object value = super .getProperty(key);
334:                if (value == null) {
335:                    return parentCloud.getProperty(key);
336:                } else {
337:                    return value;
338:                }
339:            }
340:
341:            /**
342:             * @see org.mmbase.bridge.Transaction#getCloudName()
343:             */
344:            public String getCloudName() {
345:                if (parentCloud instanceof  Transaction) {
346:                    return ((Transaction) parentCloud).getCloudName();
347:                } else {
348:                    return parentCloud.getName();
349:                }
350:            }
351:
352:            private void readObject(ObjectInputStream in) throws IOException,
353:                    ClassNotFoundException {
354:                _readObject(in);
355:                transactionContext = (String) in.readObject();
356:                canceled = in.readBoolean();
357:                committed = in.readBoolean();
358:                transactionName = (String) in.readObject();
359:                parentCloud = (BasicCloud) in.readObject();
360:            }
361:
362:            private void writeObject(ObjectOutputStream out) throws IOException {
363:                _writeObject(out);
364:                out.writeObject(transactionContext);
365:                out.writeBoolean(canceled);
366:                out.writeBoolean(committed);
367:                out.writeObject(transactionName);
368:                out.writeObject(parentCloud);
369:            }
370:
371:            public String toString() {
372:                UserContext uc = getUser();
373:                return "BasicTransaction " + count + "'" + getName() + "' of "
374:                        + (uc != null ? uc.getIdentifier() : "NO USER YET")
375:                        + " @" + Integer.toHexString(hashCode());
376:            }
377:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.