Source Code Cross Referenced for DatabaseObject.java in  » J2EE » hgcommons » biz » hammurapi » sql » 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 » hgcommons » biz.hammurapi.sql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * hgcommons 7
003:         * Hammurapi Group Common Library 
004:         * Copyright (C) 2003  Hammurapi Group
005:         *
006:         * This program is free software; you can redistribute it and/or
007:         * modify it under the terms of the GNU Lesser General Public
008:         * License as published by the Free Software Foundation; either
009:         * version 2 of the License, or (at your option) any later version.
010:         *
011:         * This program is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         * Lesser General Public License for more details.
015:         *
016:         * You should have received a copy of the GNU Lesser General Public
017:         * License along with this library; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         *
020:         * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
021:         * e-Mail: support@hammurapi.biz
022:         */
023:        package biz.hammurapi.sql;
024:
025:        import java.io.Serializable;
026:        import java.lang.reflect.Constructor;
027:        import java.lang.reflect.InvocationTargetException;
028:        import java.sql.PreparedStatement;
029:        import java.sql.SQLException;
030:        import java.sql.Types;
031:        import java.util.AbstractList;
032:        import java.util.ArrayList;
033:        import java.util.Collection;
034:        import java.util.HashMap;
035:        import java.util.HashSet;
036:        import java.util.Iterator;
037:        import java.util.Map;
038:        import java.util.Properties;
039:        import java.util.Set;
040:        import java.util.Map.Entry;
041:
042:        import javax.xml.transform.TransformerException;
043:
044:        import org.apache.xpath.CachedXPathAPI;
045:        import org.apache.xpath.XPathAPI;
046:        import org.w3c.dom.Element;
047:        import org.w3c.dom.Node;
048:        import org.w3c.dom.traversal.NodeIterator;
049:
050:        import biz.hammurapi.config.ConfigurationException;
051:        import biz.hammurapi.config.Context;
052:        import biz.hammurapi.config.ContextConfigurable;
053:        import biz.hammurapi.config.DomConfigFactory;
054:        import biz.hammurapi.config.DomConfigurable;
055:        import biz.hammurapi.convert.CompositeConverter;
056:        import biz.hammurapi.sql.columns.Column;
057:        import biz.hammurapi.sql.columns.ColumnChangeListener;
058:        import biz.hammurapi.util.Attributable;
059:        import biz.hammurapi.util.ClassResourceLoader;
060:        import biz.hammurapi.util.Observable;
061:        import biz.hammurapi.util.Observer;
062:        import biz.hammurapi.util.Versioned;
063:        import biz.hammurapi.xml.dom.AbstractDomObject;
064:        import biz.hammurapi.xml.dom.CompositeDomSerializer;
065:        import biz.hammurapi.xml.dom.DomSerializable;
066:
067:        /**
068:         * SQLC-generated interface implementations implement this method to achieve
069:         * differential update functionality - inserting and updating only modified fields.
070:         * @author Pavel Vlasov
071:         * @version $Revision: 1.11 $
072:         */
073:        public class DatabaseObject implements  DomSerializable,
074:                ColumnChangeListener, Cloneable, ContextConfigurable, Context,
075:                DomConfigurable, Attributable, Versioned, Observable,
076:                IDatabaseObject, Serializable {
077:
078:            protected Collection columns = new ArrayList();
079:            private Map columnMap = new HashMap();
080:            private boolean force;
081:            private boolean isDeleted;
082:
083:            protected Column getColumn(String name) {
084:                return (Column) columnMap.get(name);
085:            }
086:
087:            /**
088:             * Default constructor
089:             */
090:            public DatabaseObject() {
091:                // Default constructor
092:            }
093:
094:            /**
095:             * 
096:             * @param force Forces columns to be marked as 
097:             * modified if setter method is invoked even if value being set equals to existing column
098:             * value. Useful during inserts with non-nullable columns which map to primitive 
099:             * types and as such have default values.
100:             */
101:            public DatabaseObject(boolean force) {
102:                this .force = force;
103:            }
104:
105:            protected void addColumn(Column column) {
106:                column.setForce(force);
107:                columns.add(column);
108:                columnMap.put(column.getName(), column);
109:                column.setListener(this );
110:            }
111:
112:            /* (non-Javadoc)
113:             * @see biz.hammurapi.sql.IDatabaseObject#update(biz.hammurapi.sql.SQLProcessor, java.lang.String)
114:             */
115:            public int update(SQLProcessor processor, String tableName)
116:                    throws SQLException {
117:                StringBuffer sb = new StringBuffer("UPDATE ");
118:                sb.append(tableName);
119:                sb.append(" SET ");
120:                boolean hasColumns = false;
121:                Iterator it = columns.iterator();
122:                while (it.hasNext()) {
123:                    Column column = (Column) it.next();
124:                    String colName = (column).listName();
125:                    if (colName != null) {
126:                        if (hasColumns) {
127:                            sb.append(", ");
128:                        }
129:                        sb.append(colName);
130:                        sb.append("=?");
131:                        hasColumns = true;
132:
133:                    }
134:                }
135:
136:                if (!hasColumns) {
137:                    return 0;
138:                }
139:
140:                sb.append(" WHERE ");
141:
142:                boolean hasPkColumns = false;
143:                it = columns.iterator();
144:                while (it.hasNext()) {
145:                    Column column = (Column) it.next();
146:                    if (column.isPrimaryKey()) {
147:                        String colName = (column).getName();
148:                        if (hasPkColumns) {
149:                            sb.append(" AND ");
150:                        }
151:                        sb.append(colName);
152:                        sb.append("=?");
153:                        hasPkColumns = true;
154:                    }
155:                }
156:
157:                int ret = processor.processUpdate(sb.toString(),
158:                        new Parameterizer() {
159:                            public void parameterize(PreparedStatement ps)
160:                                    throws SQLException {
161:                                int idx = 1;
162:                                Iterator it = columns.iterator();
163:                                while (it.hasNext()) {
164:                                    Column column = (Column) it.next();
165:                                    idx = column.parameterize(ps, idx, false);
166:                                }
167:
168:                                it = columns.iterator();
169:                                while (it.hasNext()) {
170:                                    Column column = (Column) it.next();
171:                                    if (column.isPrimaryKey()) {
172:                                        column.parameterizeOriginal(ps, idx++);
173:                                    }
174:                                }
175:                            }
176:                        });
177:
178:                it = columns.iterator();
179:                while (it.hasNext()) {
180:                    ((Column) it.next()).clearModified();
181:                }
182:
183:                originalVersion = objectVersion;
184:                isModified = false;
185:
186:                storeRelationships(processor);
187:
188:                it = relationships.iterator();
189:                while (it.hasNext()) {
190:                    RelationshipEntry re = (RelationshipEntry) it.next();
191:                    if (re.name != null) {
192:                        Iterator iit = re.items.iterator();
193:                        while (iit.hasNext()) {
194:                            IDatabaseObject subItem = (IDatabaseObject) iit
195:                                    .next();
196:                            if (subItem.isModified()) {
197:                                re.items.update(processor, subItem);
198:                                subItem.update(processor, null);
199:                            }
200:                        }
201:                    }
202:                }
203:                return ret;
204:            }
205:
206:            /* (non-Javadoc)
207:             * @see biz.hammurapi.sql.IDatabaseObject#delete(biz.hammurapi.sql.SQLProcessor, java.lang.String)
208:             */
209:            public int delete(SQLProcessor processor, String tableName)
210:                    throws SQLException {
211:                storeRelationships(processor);
212:
213:                StringBuffer sb = new StringBuffer("DELETE FROM ");
214:                sb.append(tableName);
215:                sb.append(" WHERE ");
216:
217:                boolean hasPkColumns = false;
218:                Iterator it = columns.iterator();
219:                while (it.hasNext()) {
220:                    Column column = (Column) it.next();
221:                    if (column.isPrimaryKey()) {
222:                        String colName = (column).getName();
223:                        if (hasPkColumns) {
224:                            sb.append(" AND ");
225:                        }
226:                        sb.append(colName);
227:                        sb.append("=?");
228:                        hasPkColumns = true;
229:                    }
230:                }
231:
232:                int ret = processor.processUpdate(sb.toString(),
233:                        new Parameterizer() {
234:                            public void parameterize(PreparedStatement ps)
235:                                    throws SQLException {
236:                                int idx = 1;
237:                                Iterator it = columns.iterator();
238:                                while (it.hasNext()) {
239:                                    Column column = (Column) it.next();
240:                                    if (!column.isPrimaryKey()) {
241:                                        idx = column.parameterize(ps, idx,
242:                                                false);
243:                                    }
244:                                }
245:
246:                                it = columns.iterator();
247:                                while (it.hasNext()) {
248:                                    Column column = (Column) it.next();
249:                                    if (column.isPrimaryKey()) {
250:                                        idx = column
251:                                                .parameterize(ps, idx, true);
252:                                    }
253:                                }
254:                            }
255:                        });
256:
257:                it = columns.iterator();
258:                while (it.hasNext()) {
259:                    ((Column) it.next()).clearModified();
260:                }
261:
262:                originalVersion = objectVersion;
263:                isDeleted = true;
264:                return ret;
265:            }
266:
267:            /* (non-Javadoc)
268:             * @see biz.hammurapi.sql.IDatabaseObject#insert(biz.hammurapi.sql.SQLProcessor, java.lang.String)
269:             */
270:            public int insert(SQLProcessor processor, String tableName)
271:                    throws SQLException {
272:                StringBuffer sb = new StringBuffer("INSERT INTO ");
273:                sb.append(tableName);
274:                sb.append(" (");
275:                int columnsCounter = 0;
276:                Iterator it = columns.iterator();
277:                while (it.hasNext()) {
278:                    String colName = ((Column) it.next()).listName();
279:                    if (colName != null) {
280:                        if (columnsCounter > 0) {
281:                            sb.append(", ");
282:                        }
283:                        sb.append(colName);
284:                        columnsCounter++;
285:
286:                    }
287:                }
288:
289:                if (columnsCounter == 0) {
290:                    return 0;
291:                }
292:
293:                sb.append(") VALUES (");
294:                for (int i = 0; i < columnsCounter; i++) {
295:                    if (i > 0) {
296:                        sb.append(", ");
297:                    }
298:                    sb.append("?");
299:                }
300:                sb.append(")");
301:
302:                int ret = processor.processUpdate(sb.toString(),
303:                        new Parameterizer() {
304:                            public void parameterize(PreparedStatement ps)
305:                                    throws SQLException {
306:                                Iterator it = columns.iterator();
307:                                for (int i = 1; it.hasNext(); i = ((Column) it
308:                                        .next()).parameterize(ps, i, false))
309:                                    ;
310:                            }
311:                        });
312:
313:                it = columns.iterator();
314:                while (it.hasNext()) {
315:                    ((Column) it.next()).clearModified();
316:                }
317:
318:                originalVersion = objectVersion;
319:                isModified = false;
320:
321:                storeRelationships(processor);
322:                return ret;
323:            }
324:
325:            /* (non-Javadoc)
326:             * @see biz.hammurapi.sql.IDatabaseObject#fromDom(org.w3c.dom.Element)
327:             */
328:            public void fromDom(Element holder) throws ConfigurationException {
329:                fromDom(holder, getNameMap(getClass()));
330:            }
331:
332:            private void loadAttributes(Element holder)
333:                    throws ConfigurationException {
334:                DomConfigFactory dcf = new DomConfigFactory();
335:                attributes.clear();
336:                try {
337:                    Node attributesNode = XPathAPI.selectSingleNode(holder,
338:                            "object-attributes");
339:                    if (attributesNode != null) {
340:                        attributes.putAll((Map) dcf.create(attributesNode));
341:                    }
342:                } catch (TransformerException e) {
343:                    throw new ConfigurationException(
344:                            "Cannot load database object attributes: " + e, e);
345:                }
346:
347:            }
348:
349:            /* (non-Javadoc)
350:             * @see biz.hammurapi.sql.IDatabaseObject#fromDom(org.w3c.dom.Element, java.util.Properties)
351:             */
352:            public void fromDom(Element holder, Properties nameMap)
353:                    throws ConfigurationException {
354:                CachedXPathAPI cxpa = new CachedXPathAPI();
355:                Iterator it = columns.iterator();
356:                while (it.hasNext()) {
357:                    Column column = (Column) it.next();
358:                    String nodeName = nameMap.getProperty(column.getName(),
359:                            column.getName()).trim();
360:
361:                    if (nodeName.length() == 0) {
362:                        // Zero mapping
363:                        continue;
364:                    } else if (nodeName.startsWith("@")) {
365:                        // Attribute mapping
366:                        if (holder.hasAttribute(nodeName.substring(1))) {
367:                            column.load(holder.getAttribute(nodeName
368:                                    .substring(1)));
369:                        }
370:                    } else if (nodeName.equals(".")) {
371:                        // Text content mapping
372:                        column.load(AbstractDomObject.getElementText(holder));
373:                    } else if (nodeName.startsWith("!")) {
374:                        // Simple node mapping
375:                        try {
376:                            Node cNode = cxpa.selectSingleNode(holder, nodeName
377:                                    .substring(1));
378:                            if (cNode != null) {
379:                                column.load(AbstractDomObject
380:                                        .getElementText(cNode));
381:                            }
382:                        } catch (TransformerException e) {
383:                            throw new ConfigurationException(
384:                                    "Cannot load column " + column.getName());
385:                        }
386:                    } else {
387:                        // Regular node mapping
388:                        try {
389:                            Node cNode = cxpa
390:                                    .selectSingleNode(holder, nodeName);
391:                            if (cNode != null) {
392:                                column.configure(cNode, null);
393:                            }
394:                        } catch (TransformerException e) {
395:                            throw new ConfigurationException(
396:                                    "Cannot load column " + column.getName());
397:                        }
398:                    }
399:                }
400:
401:                it = relationships.iterator();
402:                while (it.hasNext()) {
403:                    RelationshipEntry re = (RelationshipEntry) it.next();
404:                    if (re.name != null) {
405:                        String domName = re.domName == null ? re.name
406:                                : re.domName;
407:                        try {
408:                            Constructor constructor = re.items.relationship
409:                                    .getItemType().getConstructor(
410:                                            new Class[] { Element.class,
411:                                                    boolean.class });
412:                            Element rel = ".".equals(domName) ? holder
413:                                    : (Element) cxpa.selectSingleNode(holder,
414:                                            domName);
415:                            String itemName = re.itemName == null ? "element"
416:                                    : re.itemName;
417:                            Element itemElement;
418:                            NodeIterator nit = cxpa.selectNodeIterator(rel,
419:                                    itemName);
420:                            while ((itemElement = (Element) nit.nextNode()) != null) {
421:                                re.items.add(constructor
422:                                        .newInstance(new Object[] {
423:                                                itemElement,
424:                                                force ? Boolean.TRUE
425:                                                        : Boolean.FALSE }));
426:                            }
427:                        } catch (TransformerException e) {
428:                            throw new ConfigurationException(
429:                                    "Cannot load relationship " + re.name, e);
430:                        } catch (InstantiationException e) {
431:                            throw new ConfigurationException(
432:                                    "Cannot load relationship " + re.name, e);
433:                        } catch (IllegalAccessException e) {
434:                            throw new ConfigurationException(
435:                                    "Cannot load relationship " + re.name, e);
436:                        } catch (InvocationTargetException e) {
437:                            throw new ConfigurationException(
438:                                    "Cannot load relationship " + re.name, e);
439:                        } catch (SecurityException e) {
440:                            throw new ConfigurationException(
441:                                    "Cannot load relationship " + re.name, e);
442:                        } catch (NoSuchMethodException e) {
443:                            throw new ConfigurationException(
444:                                    "Cannot load relationship " + re.name, e);
445:                        }
446:                    }
447:                }
448:                loadAttributes(holder);
449:            }
450:
451:            public void toDom(Element holder) {
452:                toDom(holder, getNameMap(getClass()), false);
453:            }
454:
455:            /* (non-Javadoc)
456:             * @see biz.hammurapi.sql.IDatabaseObject#toDom(org.w3c.dom.Element, java.util.Properties, boolean)
457:             */
458:            public void toDom(Element holder, Properties nameMap,
459:                    boolean originals) {
460:                if (nameMap == null) {
461:                    nameMap = new Properties();
462:                }
463:
464:                String cna = nameMap.getProperty("@type", "type").trim();
465:                if (!"".equals(cna)) {
466:                    holder.setAttribute(cna, getClass().getName());
467:                }
468:
469:                Iterator it = columns.iterator();
470:                while (it.hasNext()) {
471:                    Column column = (Column) it.next();
472:                    column.toDom(holder, nameMap.getProperty(column.getName(),
473:                            column.getName()).trim(), originals);
474:                }
475:
476:                it = relationships.iterator();
477:                while (it.hasNext()) {
478:                    RelationshipEntry re = (RelationshipEntry) it.next();
479:                    if (re.name != null) {
480:                        String domName = re.domName == null ? re.name
481:                                : re.domName;
482:                        Element rel = ".".equals(domName) ? holder : holder
483:                                .getOwnerDocument().createElement(domName);
484:                        if (rel != holder) {
485:                            holder.appendChild(rel);
486:                        }
487:
488:                        Iterator iit = re.items.iterator();
489:                        while (iit.hasNext()) {
490:                            String itemName = re.itemName == null ? "element"
491:                                    : re.itemName;
492:                            Element ie = holder.getOwnerDocument()
493:                                    .createElement(itemName);
494:                            rel.appendChild(ie);
495:                            ((DatabaseObject) iit.next()).toDom(ie);
496:                        }
497:                    }
498:                }
499:
500:                if (!attributes.isEmpty()) {
501:                    CompositeDomSerializer.getThreadInstance()
502:                            .toDomSerializable(attributes).toDom(
503:                                    AbstractDomObject.addElement(holder,
504:                                            "object-attributes"));
505:                }
506:            }
507:
508:            public String toString() {
509:                StringBuffer ret = new StringBuffer(getClass().getName());
510:                ret.append("[");
511:                Iterator it = columns.iterator();
512:                while (it.hasNext()) {
513:                    ret.append(it.next());
514:                    if (it.hasNext()) {
515:                        ret.append(", ");
516:                    }
517:                }
518:
519:                ret.append("]");
520:                return ret.toString();
521:            }
522:
523:            /**
524:             * Sets modified flag to true and increments version number.
525:             * Also broadcasts the change to observers. Changed column is
526:             * passed as second argument of update() method.
527:             * Override this method in subclasses to react on 
528:             * change events, but don't forget to invoke 
529:             * super.onChange().
530:             * @param column Changed column
531:             */
532:            public void onChange(Column column) {
533:                isModified = true;
534:
535:                ++objectVersion;
536:
537:                if (column.isPrimaryKey()) {
538:                    isDeleted = false;
539:                }
540:
541:                Iterator it = relationships.iterator();
542:                while (it.hasNext()) {
543:                    Relationship relationship = ((RelationshipEntry) it.next()).items.relationship;
544:                    if (relationship instanceof  ColumnChangeListener) {
545:                        ((ColumnChangeListener) relationship).onChange(column);
546:                    }
547:                }
548:
549:                synchronized (observers) {
550:                    it = observers.iterator();
551:                    while (it.hasNext()) {
552:                        ((Observer) it.next()).update(this , column);
553:                    }
554:                }
555:
556:            }
557:
558:            /* (non-Javadoc)
559:             * @see biz.hammurapi.sql.IDatabaseObject#setOriginal()
560:             */
561:            public void setOriginal() {
562:                objectVersion = originalVersion;
563:                Iterator it = columns.iterator();
564:                while (it.hasNext()) {
565:                    ((Column) it.next()).setOriginal();
566:                }
567:            }
568:
569:            private boolean isModified = false;
570:
571:            /* (non-Javadoc)
572:             * @see biz.hammurapi.sql.IDatabaseObject#isModified()
573:             */
574:            public boolean isModified() {
575:                return isModified;
576:            }
577:
578:            /* (non-Javadoc)
579:             * @see biz.hammurapi.sql.IDatabaseObject#isDeleted()
580:             */
581:            public boolean isDeleted() {
582:                return isDeleted;
583:            }
584:
585:            /**
586:             * Two objects are considered equal and all their fields are equal.
587:             * @param otherBean Other object
588:             * @return true if object classes are equal and all member column values are
589:             * equal.
590:             */
591:            public boolean equals(Object otherBean) {
592:                if (otherBean == null) {
593:                    return false;
594:                } else if (getClass().equals(otherBean.getClass())) {
595:                    Collection myColumns = new ArrayList(columns);
596:                    Collection otherColumns = new ArrayList(
597:                            ((DatabaseObject) otherBean).columns);
598:                    Iterator mcit = myColumns.iterator();
599:                    Z: while (mcit.hasNext()) {
600:                        Column mc = (Column) mcit.next();
601:                        Iterator ocit = otherColumns.iterator();
602:                        while (ocit.hasNext()) {
603:                            Column oc = (Column) ocit.next();
604:                            if (mc.getName().equals(oc.getName())) {
605:                                if (mc.equals(oc)) {
606:                                    ocit.remove();
607:                                    mcit.remove();
608:                                    continue Z;
609:                                }
610:
611:                                return false;
612:                            }
613:                        }
614:                    }
615:
616:                    return myColumns.isEmpty() && otherColumns.isEmpty();
617:                } else {
618:                    return false;
619:                }
620:            }
621:
622:            public int hashCode() {
623:                int ret = 0;
624:                Iterator cit = columns.iterator();
625:                while (cit.hasNext()) {
626:                    ret ^= cit.next().hashCode();
627:                }
628:                return ret;
629:            }
630:
631:            /**
632:             * Clones object, clears columns collection, clears isDeleted and isModified flags. 
633:             * Subclasses shall add cloned columns.
634:             */
635:            public Object clone() throws CloneNotSupportedException {
636:                DatabaseObject ret = (DatabaseObject) super .clone();
637:                ret.columns.clear();
638:                ret.isDeleted = false;
639:                ret.isModified = false;
640:                return ret;
641:            }
642:
643:            /* (non-Javadoc)
644:             * @see biz.hammurapi.sql.IDatabaseObject#clear()
645:             */
646:            public void clear() {
647:                Iterator it = columns.iterator();
648:                while (it.hasNext()) {
649:                    ((Column) it.next()).clear();
650:                }
651:                isModified = false;
652:                isDeleted = false;
653:            }
654:
655:            public void configure(Context context, CompositeConverter converter)
656:                    throws ConfigurationException {
657:                Iterator it = columns.iterator();
658:                while (it.hasNext()) {
659:                    ((Column) it.next()).configure(context, converter);
660:                }
661:            }
662:
663:            public Object get(String name) {
664:                Column col = (Column) columnMap.get(name);
665:                return col == null ? null : col.getObjectValue(false);
666:            }
667:
668:            public void configure(Node configNode, Context context)
669:                    throws ConfigurationException {
670:                fromDom((Element) configNode);
671:            }
672:
673:            private static Map nnMap = new HashMap();
674:
675:            private static Properties getNameMap(Class clazz) {
676:                synchronized (nnMap) {
677:                    Properties ret = (Properties) nnMap.get(clazz.getName());
678:                    if (ret == null) {
679:                        ret = new ClassResourceLoader(clazz).getProperties(
680:                                null, "namemap");
681:                        nnMap.put(clazz.getName(), ret);
682:                    }
683:                    return ret;
684:                }
685:            }
686:
687:            private class RelationshipEntry {
688:                String name;
689:                String itemName;
690:                String domName;
691:                RelationshipListImpl items;
692:            }
693:
694:            private class RelationshipListImpl extends AbstractList implements 
695:                    RelationshipList {
696:                private ArrayList master = new ArrayList();
697:                private Relationship relationship;
698:                private boolean alreadyLoaded;
699:
700:                private RelationshipListImpl(Relationship relationship) {
701:                    this .relationship = relationship;
702:                    relationship.setMaster(master);
703:                }
704:
705:                private void update(SQLProcessor processor,
706:                        IDatabaseObject subItem) throws SQLException {
707:                    relationship.update(processor, subItem);
708:                }
709:
710:                private void load(SQLProcessor processor) throws SQLException {
711:                    if (!alreadyLoaded || relationship.isModified()) {
712:                        master.clear();
713:                        relationship.load(processor, master);
714:                        alreadyLoaded = true;
715:                    }
716:                }
717:
718:                private void store(SQLProcessor processor) throws SQLException {
719:                    relationship.store(processor);
720:                }
721:
722:                public Object get(int index) {
723:                    return master.get(index);
724:                }
725:
726:                public int size() {
727:                    return master.size();
728:                }
729:
730:                public boolean add(Object o) {
731:                    relationship.add((DatabaseObject) o);
732:                    return master.add(o);
733:                }
734:
735:                public boolean remove(Object o) {
736:                    relationship.remove((IDatabaseObject) o);
737:                    return master.remove(o);
738:                }
739:
740:                public boolean isLazy() {
741:                    return relationship.isLazy();
742:                }
743:
744:                public boolean isModified() {
745:                    return relationship.isModified();
746:                }
747:
748:                public IDatabaseObject add() {
749:                    try {
750:                        IDatabaseObject item = (IDatabaseObject) relationship
751:                                .getItemType().newInstance();
752:                        add(item);
753:                        return item;
754:                    } catch (InstantiationException e) {
755:                        throw new RuntimeException("Cannot instantiate "
756:                                + relationship.getItemType());
757:                    } catch (IllegalAccessException e) {
758:                        throw new RuntimeException("Cannot instantiate "
759:                                + relationship.getItemType());
760:                    }
761:                }
762:            }
763:
764:            private Collection relationships = new ArrayList();
765:            private Map relationshipMap = new HashMap();
766:
767:            protected RelationshipList getRelationship(String name) {
768:                RelationshipEntry entry = (RelationshipEntry) relationshipMap
769:                        .get(name);
770:                if (entry.items.isLazy() || entry.items.isModified()) {
771:                    try {
772:                        entry.items.load(((Lazy) this ).getProcessor());
773:                    } catch (SQLException e) {
774:                        throw new SQLRuntimeException(e);
775:                    }
776:                }
777:                return entry.items;
778:            }
779:
780:            /**
781:             * @param name Name for composite relationships to render in XML, null for shared relationships.
782:             * @param itemName name of item element in XML.
783:             * @param itemClass item class. This class shall have constructor from Element,boolean in order to load from 
784:             * XML docs.
785:             * @param relationship
786:             */
787:            protected RelationshipList addRelationship(String name,
788:                    String itemName, Relationship relationship) {
789:                if (relationship.isLazy() && !(this  instanceof  Lazy)) {
790:                    throw new IllegalArgumentException(
791:                            "Cannot add lazy relationship to class which doesn't implement Lazy interface");
792:                }
793:
794:                if (!DatabaseObject.class.isAssignableFrom(relationship
795:                        .getItemType())) {
796:                    throw new IllegalArgumentException(
797:                            "Relationship can be established only between DatabaseObject subclasses");
798:                }
799:                RelationshipEntry entry = new RelationshipEntry();
800:                relationships.add(entry);
801:                entry.name = name;
802:                entry.itemName = itemName;
803:                entry.items = new RelationshipListImpl(relationship);
804:                Properties nameMap = getNameMap(getClass());
805:                String cName = name == null ? null : nameMap.getProperty(name);
806:                entry.domName = cName == null ? null : cName.trim();
807:                relationshipMap.put(name, entry);
808:                return entry.items;
809:            }
810:
811:            /**
812:             * Use this method to eagerly load relationships in constructors.
813:             * @param processor
814:             * @throws SQLException
815:             */
816:            protected void loadRelationships(SQLProcessor processor)
817:                    throws SQLException {
818:                Iterator it = relationships.iterator();
819:                while (it.hasNext()) {
820:                    RelationshipEntry relationshipEntry = (RelationshipEntry) it
821:                            .next();
822:                    if (!relationshipEntry.items.isLazy()) {
823:                        (relationshipEntry).items.load(processor);
824:                    }
825:                }
826:            }
827:
828:            /**
829:             * Use this method to eagerly load relationships in constructors.
830:             * @param processor
831:             * @throws SQLException
832:             */
833:            private void storeRelationships(SQLProcessor processor)
834:                    throws SQLException {
835:                Iterator it = relationships.iterator();
836:                while (it.hasNext()) {
837:                    ((RelationshipEntry) it.next()).items.store(processor);
838:                }
839:            }
840:
841:            /* (non-Javadoc)
842:             * @see biz.hammurapi.sql.IDatabaseObject#copy(biz.hammurapi.sql.DatabaseObject)
843:             */
844:            public void copy(DatabaseObject source) {
845:                Iterator it = columns.iterator();
846:                while (it.hasNext()) {
847:                    Column targetColumn = (Column) it.next();
848:                    Column sourceColumn = (Column) source.columnMap
849:                            .get(targetColumn.getName());
850:                    if (targetColumn.getClass().isInstance(sourceColumn)) { // Copy values only from compatible columns
851:                        targetColumn.set(sourceColumn);
852:                    }
853:                }
854:            }
855:
856:            private Map attributes = new HashMap();
857:
858:            public void setAttribute(Object key, Object value) {
859:                attributes.put(key, value);
860:            }
861:
862:            public Object getAttribute(Object key) {
863:                return attributes.get(key);
864:            }
865:
866:            public Object removeAttribute(Object key) {
867:                return attributes.remove(key);
868:            }
869:
870:            /* (non-Javadoc)
871:             * @see biz.hammurapi.sql.IDatabaseObject#setColumnAttribute(java.lang.String, java.lang.Object, java.lang.Object)
872:             */
873:            public void setColumnAttribute(String columnName, Object key,
874:                    Object value) {
875:                Column column = (Column) columnMap.get(columnName);
876:                if (column == null) {
877:                    throw new IllegalArgumentException("Column not found: "
878:                            + columnName);
879:                }
880:                column.setAttribute(key, value);
881:            }
882:
883:            /* (non-Javadoc)
884:             * @see biz.hammurapi.sql.IDatabaseObject#getColumnAttribute(java.lang.String, java.lang.Object)
885:             */
886:            public Object getColumnAttribute(String columnName, Object key) {
887:                Column column = (Column) columnMap.get(columnName);
888:                if (column == null) {
889:                    throw new IllegalArgumentException("Column not found: "
890:                            + columnName);
891:                }
892:                return column.getAttribute(key);
893:            }
894:
895:            /* (non-Javadoc)
896:             * @see biz.hammurapi.sql.IDatabaseObject#removeColumnAttribute(java.lang.String, java.lang.Object)
897:             */
898:            public Object removeColumnAttribute(String columnName, Object key) {
899:                Column column = (Column) columnMap.get(columnName);
900:                if (column == null) {
901:                    throw new IllegalArgumentException("Column not found: "
902:                            + columnName);
903:                }
904:                return column.removeAttribute(key);
905:            }
906:
907:            private static Map sqlTypes = new HashMap();
908:
909:            /**
910:             * Allows to override generated column types with &lt;class name&gt;.sqltypes resource.
911:             * Subclasses shall use this method when dealing with Object columns.
912:             * @param columnName
913:             * @param generatedType
914:             * @return
915:             */
916:            protected int getSqlType(String columnName, int generatedType) {
917:                Map typeMap;
918:                synchronized (sqlTypes) {
919:                    String className = getClass().getName();
920:                    if (sqlTypes.containsKey(className)) {
921:                        typeMap = (Map) sqlTypes.get(className);
922:                    } else {
923:                        Properties literalMap = new ClassResourceLoader(
924:                                getClass()).getProperties(null, "sqltypes");
925:                        typeMap = new HashMap();
926:                        sqlTypes.put(className, typeMap);
927:                        Iterator it = literalMap.entrySet().iterator();
928:                        while (it.hasNext()) {
929:                            Entry entry = (Entry) it.next();
930:                            try {
931:                                Integer type = (Integer) Types.class
932:                                        .getDeclaredField(
933:                                                (String) entry.getValue()).get(
934:                                                null);
935:                                typeMap.put(entry.getKey(), type);
936:                            } catch (IllegalArgumentException e) {
937:                                System.err.println("Invalid SQL Type "
938:                                        + entry.getValue()
939:                                        + ", ignored. Cause: " + e);
940:                                e.printStackTrace();
941:                            } catch (SecurityException e) {
942:                                System.err.println("Invalid SQL Type "
943:                                        + entry.getValue()
944:                                        + ", ignored. Cause: " + e);
945:                                e.printStackTrace();
946:                            } catch (IllegalAccessException e) {
947:                                System.err.println("Invalid SQL Type "
948:                                        + entry.getValue()
949:                                        + ", ignored. Cause: " + e);
950:                                e.printStackTrace();
951:                            } catch (NoSuchFieldException e) {
952:                                System.err.println("Invalid SQL Type "
953:                                        + entry.getValue()
954:                                        + ", ignored. Cause: " + e);
955:                                e.printStackTrace();
956:                            }
957:                        }
958:                    }
959:                }
960:
961:                Integer st = (Integer) typeMap.get(columnName);
962:                return st == null ? generatedType : st.intValue();
963:            }
964:
965:            /**
966:             * Subclasses can choose to read object version from the database.
967:             */
968:            protected int objectVersion;
969:            protected int originalVersion;
970:
971:            public int getObjectVersion() {
972:                return objectVersion;
973:            }
974:
975:            private Set observers = new HashSet();
976:
977:            public void addObserver(Observer observer) {
978:                synchronized (observers) {
979:                    observers.add(observer);
980:                }
981:            }
982:
983:            public void removeObserver(Observer observer) {
984:                synchronized (observers) {
985:                    observers.remove(observer);
986:                }
987:            }
988:
989:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.