Source Code Cross Referenced for ForeignKey.java in  » Database-ORM » openjpa » org » apache » openjpa » jdbc » schema » 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 » openjpa » org.apache.openjpa.jdbc.schema 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one
003:         * or more contributor license agreements.  See the NOTICE file
004:         * distributed with this work for additional information
005:         * regarding copyright ownership.  The ASF licenses this file
006:         * to you under the Apache License, Version 2.0 (the
007:         * "License"); you may not use this file except in compliance
008:         * with the License.  You may obtain a copy of the License at
009:         *
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing,
013:         * software distributed under the License is distributed on an
014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015:         * KIND, either express or implied.  See the License for the
016:         * specific language governing permissions and limitations
017:         * under the License.    
018:         */
019:        package org.apache.openjpa.jdbc.schema;
020:
021:        import java.sql.DatabaseMetaData;
022:        import java.util.ArrayList;
023:        import java.util.Arrays;
024:        import java.util.List;
025:        import java.util.LinkedHashMap;
026:
027:        import org.apache.commons.lang.ObjectUtils;
028:        import org.apache.openjpa.lib.util.Localizer;
029:        import org.apache.openjpa.lib.util.StringDistance;
030:        import org.apache.openjpa.util.InvalidStateException;
031:
032:        /**
033:         * Represents a database foreign key; may be a logical key with no
034:         * database representation. This class can also represent a partial key,
035:         * aligning with {@link DatabaseMetaData}.
036:         *
037:         * @author Abe White
038:         */
039:        public class ForeignKey extends Constraint {
040:
041:            /**
042:             * Logical foreign key; links columns, but does not perform any action
043:             * when the joined primary key columns are modified.
044:             */
045:            public static final int ACTION_NONE = 1;
046:
047:            /**
048:             * Throw an exception if joined primary key columns are modified.
049:             */
050:            public static final int ACTION_RESTRICT = 2;
051:
052:            /**
053:             * Cascade any modification of the joined primary key columns to
054:             * this table. If the joined primary key row is deleted, the row in this
055:             * table will also be deleted.
056:             */
057:            public static final int ACTION_CASCADE = 3;
058:
059:            /**
060:             * Null the local columns if the joined primary key columns are modified.
061:             */
062:            public static final int ACTION_NULL = 4;
063:
064:            /**
065:             * Set the local columns to their default values if the primary key
066:             * columns are modified.
067:             */
068:            public static final int ACTION_DEFAULT = 5;
069:
070:            private static final Localizer _loc = Localizer
071:                    .forPackage(ForeignKey.class);
072:
073:            private String _pkTableName = null;
074:            private String _pkSchemaName = null;
075:            private String _pkColumnName = null;
076:            private int _seq = 0;
077:
078:            private LinkedHashMap _joins = null;
079:            private LinkedHashMap _joinsPK = null;
080:            private LinkedHashMap _consts = null;
081:            private LinkedHashMap _constsPK = null;
082:            private int _delAction = ACTION_NONE;
083:            private int _upAction = ACTION_NONE;
084:            private int _index = 0;
085:
086:            // cached items
087:            private Column[] _locals = null;
088:            private Column[] _pks = null;
089:            private Object[] _constVals = null;
090:            private Column[] _constCols = null;
091:            private Object[] _constValsPK = null;
092:            private Column[] _constColsPK = null;
093:            private Table _pkTable = null;
094:            private Boolean _autoAssign = null;
095:
096:            /**
097:             * Return the foreign key action constant for the given action name.
098:             */
099:            public static int getAction(String name) {
100:                if (name == null || "none".equalsIgnoreCase(name))
101:                    return ACTION_NONE;
102:                if ("cascade".equalsIgnoreCase(name))
103:                    return ACTION_CASCADE;
104:                if ("default".equalsIgnoreCase(name))
105:                    return ACTION_DEFAULT;
106:                if ("restrict".equalsIgnoreCase(name)
107:                        || "exception".equalsIgnoreCase(name))
108:                    return ACTION_RESTRICT;
109:                if ("null".equalsIgnoreCase(name))
110:                    return ACTION_NULL;
111:
112:                // not a recognized action; check for typo
113:                List recognized = Arrays
114:                        .asList(new String[] { "none", "exception", "restrict",
115:                                "cascade", "null", "default", });
116:                String closest = StringDistance.getClosestLevenshteinDistance(
117:                        name, recognized, .5F);
118:
119:                String msg;
120:                if (closest != null)
121:                    msg = _loc.get("bad-fk-action-hint", name, closest,
122:                            recognized).getMessage();
123:                else
124:                    msg = _loc.get("bad-fk-action", name, recognized)
125:                            .getMessage();
126:                throw new IllegalArgumentException(msg);
127:            }
128:
129:            /**
130:             * Return the foreign key action name for the given action constant.
131:             */
132:            public static String getActionName(int action) {
133:                switch (action) {
134:                case ACTION_NONE:
135:                    return "none";
136:                case ACTION_RESTRICT:
137:                    return "restrict";
138:                case ACTION_CASCADE:
139:                    return "cascade";
140:                case ACTION_DEFAULT:
141:                    return "default";
142:                case ACTION_NULL:
143:                    return "null";
144:                default:
145:                    throw new IllegalArgumentException(String.valueOf(action));
146:                }
147:            }
148:
149:            /**
150:             * Default constructor.
151:             */
152:            public ForeignKey() {
153:            }
154:
155:            /**
156:             * Constructor.
157:             *
158:             * @param name the foreign key name, if any
159:             * @param table the local table of the foreign key
160:             */
161:            public ForeignKey(String name, Table table) {
162:                super (name, table);
163:            }
164:
165:            public boolean isLogical() {
166:                return _delAction == ACTION_NONE;
167:            }
168:
169:            /**
170:             * Whether the primary key columns of this key are auto-incrementing, or
171:             * whether they themselves are members of a foreign key who's primary key
172:             * is auto-incrementing (recursing to arbitrary depth).
173:             */
174:            public boolean isPrimaryKeyAutoAssigned() {
175:                if (_autoAssign != null)
176:                    return _autoAssign.booleanValue();
177:                return isPrimaryKeyAutoAssigned(new ArrayList(3));
178:            }
179:
180:            /**
181:             * Helper to calculate whether this foreign key depends on auto-assigned 
182:             * columns.  Recurses appropriately if the primary key columns this key
183:             * joins to are themselves members of a foreign key that is dependent on
184:             * auto-assigned columns.  Caches calculated auto-assign value as a side 
185:             * effect.
186:             *
187:             * @param seen track seen foreign keys to prevent infinite recursion in
188:             * the case of foreign key cycles
189:             */
190:            private boolean isPrimaryKeyAutoAssigned(List seen) {
191:                if (_autoAssign != null)
192:                    return _autoAssign.booleanValue();
193:
194:                Column[] cols = getPrimaryKeyColumns();
195:                if (cols.length == 0) {
196:                    _autoAssign = Boolean.FALSE;
197:                    return false;
198:                }
199:
200:                for (int i = 0; i < cols.length; i++) {
201:                    if (cols[i].isAutoAssigned()) {
202:                        _autoAssign = Boolean.TRUE;
203:                        return true;
204:                    }
205:                }
206:
207:                ForeignKey[] fks = _pkTable.getForeignKeys();
208:                seen.add(this );
209:                for (int i = 0; i < cols.length; i++) {
210:                    for (int j = 0; j < fks.length; j++) {
211:                        if (!fks[j].containsColumn(cols[i]))
212:                            continue;
213:                        if (!seen.contains(fks[j])
214:                                && fks[j].isPrimaryKeyAutoAssigned(seen)) {
215:                            _autoAssign = Boolean.TRUE;
216:                            return true;
217:                        }
218:                    }
219:                }
220:
221:                _autoAssign = Boolean.FALSE;
222:                return false;
223:            }
224:
225:            /**
226:             * The name of the primary key table.
227:             */
228:            public String getPrimaryKeyTableName() {
229:                Table table = getPrimaryKeyTable();
230:                if (table != null)
231:                    return table.getName();
232:                return _pkTableName;
233:            }
234:
235:            /**
236:             * The name of the primary key table. You can only set the primary
237:             * key table name on foreign keys that have not already been joined.
238:             */
239:            public void setPrimaryKeyTableName(String pkTableName) {
240:                if (getPrimaryKeyTable() != null)
241:                    throw new IllegalStateException();
242:                _pkTableName = pkTableName;
243:            }
244:
245:            /**
246:             * The name of the primary key table's schema.
247:             */
248:            public String getPrimaryKeySchemaName() {
249:                Table table = getPrimaryKeyTable();
250:                if (table != null)
251:                    return table.getSchemaName();
252:                return _pkSchemaName;
253:            }
254:
255:            /**
256:             * The name of the primary key table's schema. You can only set the
257:             * primary key schema name on foreign keys that have not already been
258:             * joined.
259:             */
260:            public void setPrimaryKeySchemaName(String pkSchemaName) {
261:                if (getPrimaryKeyTable() != null)
262:                    throw new IllegalStateException();
263:                _pkSchemaName = pkSchemaName;
264:            }
265:
266:            /**
267:             * The name of the primary key column.
268:             */
269:            public String getPrimaryKeyColumnName() {
270:                return _pkColumnName;
271:            }
272:
273:            /**
274:             * The name of the primary key column. You can only set the
275:             * primary key column name on foreign keys that have not already been
276:             * joined.
277:             */
278:            public void setPrimaryKeyColumnName(String pkColumnName) {
279:                if (getPrimaryKeyTable() != null)
280:                    throw new IllegalStateException();
281:                _pkColumnName = pkColumnName;
282:            }
283:
284:            /**
285:             * The sequence of this join in the foreign key.
286:             */
287:            public int getKeySequence() {
288:                return _seq;
289:            }
290:
291:            /**
292:             * The sequence of this join in the foreign key.
293:             */
294:            public void setKeySequence(int seq) {
295:                _seq = seq;
296:            }
297:
298:            /**
299:             * Return the delete action for the key. Will be one of:
300:             * {@link #ACTION_NONE}, {@link #ACTION_RESTRICT},
301:             * {@link #ACTION_CASCADE}, {@link #ACTION_NULL}, {@link #ACTION_DEFAULT}.
302:             */
303:            public int getDeleteAction() {
304:                return _delAction;
305:            }
306:
307:            /**
308:             * Set the delete action for the key. Must be one of:
309:             * {@link #ACTION_NONE}, {@link #ACTION_RESTRICT},
310:             * {@link #ACTION_CASCADE}, {@link #ACTION_NULL}, {@link #ACTION_DEFAULT}.
311:             */
312:            public void setDeleteAction(int action) {
313:                _delAction = action;
314:                if (action == ACTION_NONE)
315:                    _upAction = ACTION_NONE;
316:                else if (_upAction == ACTION_NONE)
317:                    _upAction = ACTION_RESTRICT;
318:            }
319:
320:            /**
321:             * Return the update action for the key. Will be one of:
322:             * {@link #ACTION_NONE}, {@link #ACTION_RESTRICT},
323:             * {@link #ACTION_CASCADE}, {@link #ACTION_NULL}, {@link #ACTION_DEFAULT}.
324:             */
325:            public int getUpdateAction() {
326:                return _upAction;
327:            }
328:
329:            /**
330:             * Set the update action for the key. Must be one of:
331:             * {@link #ACTION_NONE}, {@link #ACTION_RESTRICT},
332:             * {@link #ACTION_CASCADE}, {@link #ACTION_NULL}, {@link #ACTION_DEFAULT}.
333:             */
334:            public void setUpdateAction(int action) {
335:                _upAction = action;
336:                if (action == ACTION_NONE)
337:                    _delAction = ACTION_NONE;
338:                else if (_delAction == ACTION_NONE)
339:                    _delAction = ACTION_RESTRICT;
340:            }
341:
342:            /**
343:             * Return the foreign key's 0-based index in the owning table.
344:             */
345:            public int getIndex() {
346:                Table table = getTable();
347:                if (table != null)
348:                    table.indexForeignKeys();
349:                return _index;
350:            }
351:
352:            /**
353:             * Set the foreign key's 0-based index in the owning table.
354:             */
355:            void setIndex(int index) {
356:                _index = index;
357:            }
358:
359:            /**
360:             * Return the primary key column joined to the given local column.
361:             */
362:            public Column getPrimaryKeyColumn(Column local) {
363:                return (_joins == null) ? null : (Column) _joins.get(local);
364:            }
365:
366:            /**
367:             * Return the local column joined to the given primary key column.
368:             */
369:            public Column getColumn(Column pk) {
370:                return (_joinsPK == null) ? null : (Column) _joinsPK.get(pk);
371:            }
372:
373:            /**
374:             * Return the constant value assigned to the given local column.
375:             */
376:            public Object getConstant(Column local) {
377:                return (_consts == null) ? null : _consts.get(local);
378:            }
379:
380:            /**
381:             * Return the constant value assigned to the given primary key column.
382:             */
383:            public Object getPrimaryKeyConstant(Column pk) {
384:                return (_constsPK == null) ? null : _constsPK.get(pk);
385:            }
386:
387:            /**
388:             * Return the local columns in the foreign key local table order.
389:             */
390:            public Column[] getColumns() {
391:                if (_locals == null)
392:                    _locals = (_joins == null) ? Schemas.EMPTY_COLUMNS
393:                            : (Column[]) _joins.keySet().toArray(
394:                                    new Column[_joins.size()]);
395:                return _locals;
396:            }
397:
398:            /**
399:             * Return the constant values assigned to the local columns
400:             * returned by {@link #getConstantColumns}.
401:             */
402:            public Object[] getConstants() {
403:                if (_constVals == null)
404:                    _constVals = (_consts == null) ? Schemas.EMPTY_VALUES
405:                            : _consts.values().toArray();
406:                return _constVals;
407:            }
408:
409:            /**
410:             * Return the constant values assigned to the primary key columns
411:             * returned by {@link #getConstantPrimaryKeyColumns}.
412:             */
413:            public Object[] getPrimaryKeyConstants() {
414:                if (_constValsPK == null)
415:                    _constValsPK = (_constsPK == null) ? Schemas.EMPTY_VALUES
416:                            : _constsPK.values().toArray();
417:                return _constValsPK;
418:            }
419:
420:            /**
421:             * Return true if the fk includes the given local column.
422:             */
423:            public boolean containsColumn(Column col) {
424:                return _joins != null && _joins.containsKey(col);
425:            }
426:
427:            /**
428:             * Return true if the fk includes the given primary key column.
429:             */
430:            public boolean containsPrimaryKeyColumn(Column col) {
431:                return _joinsPK != null && _joinsPK.containsKey(col);
432:            }
433:
434:            /**
435:             * Return true if the fk includes the given local column.
436:             */
437:            public boolean containsConstantColumn(Column col) {
438:                return _consts != null && _consts.containsKey(col);
439:            }
440:
441:            /**
442:             * Return true if the fk includes the given primary key column.
443:             */
444:            public boolean containsConstantPrimaryKeyColumn(Column col) {
445:                return _constsPK != null && _constsPK.containsKey(col);
446:            }
447:
448:            /**
449:             * Return the foreign columns in the foreign key, in join-order with
450:             * the result of {@link #getColumns}.
451:             */
452:            public Column[] getPrimaryKeyColumns() {
453:                if (_pks == null)
454:                    _pks = (_joins == null) ? Schemas.EMPTY_COLUMNS
455:                            : (Column[]) _joins.values().toArray(
456:                                    new Column[_joins.size()]);
457:                return _pks;
458:            }
459:
460:            /**
461:             * Return the local columns that we link to using constant values.
462:             */
463:            public Column[] getConstantColumns() {
464:                if (_constCols == null)
465:                    _constCols = (_consts == null) ? Schemas.EMPTY_COLUMNS
466:                            : (Column[]) _consts.keySet().toArray(
467:                                    new Column[_consts.size()]);
468:                return _constCols;
469:            }
470:
471:            /**
472:             * Return the primary key columns that we link to using constant values.
473:             */
474:            public Column[] getConstantPrimaryKeyColumns() {
475:                if (_constColsPK == null)
476:                    _constColsPK = (_constsPK == null) ? Schemas.EMPTY_COLUMNS
477:                            : (Column[]) _constsPK.keySet().toArray(
478:                                    new Column[_constsPK.size()]);
479:                return _constColsPK;
480:            }
481:
482:            /**
483:             * Set the foreign key's joins.
484:             */
485:            public void setJoins(Column[] cols, Column[] pkCols) {
486:                Column[] cur = getColumns();
487:                for (int i = 0; i < cur.length; i++)
488:                    removeJoin(cur[i]);
489:
490:                if (cols != null)
491:                    for (int i = 0; i < cols.length; i++)
492:                        join(cols[i], pkCols[i]);
493:            }
494:
495:            /**
496:             * Set the foreign key's constant joins.
497:             */
498:            public void setConstantJoins(Object[] consts, Column[] pkCols) {
499:                Column[] cur = getConstantPrimaryKeyColumns();
500:                for (int i = 0; i < cur.length; i++)
501:                    removeJoin(cur[i]);
502:
503:                if (consts != null)
504:                    for (int i = 0; i < consts.length; i++)
505:                        joinConstant(consts[i], pkCols[i]);
506:            }
507:
508:            /**
509:             * Set the foreign key's constant joins.
510:             */
511:            public void setConstantJoins(Column[] cols, Object[] consts) {
512:                Column[] cur = getConstantColumns();
513:                for (int i = 0; i < cur.length; i++)
514:                    removeJoin(cur[i]);
515:
516:                if (consts != null)
517:                    for (int i = 0; i < consts.length; i++)
518:                        joinConstant(cols[i], consts[i]);
519:            }
520:
521:            /**
522:             * Join a local column to a primary key column of another table.
523:             */
524:            public void join(Column local, Column toPK) {
525:                if (!ObjectUtils.equals(local.getTable(), getTable()))
526:                    throw new InvalidStateException(_loc.get("table-mismatch",
527:                            local.getTable(), getTable()));
528:
529:                Table pkTable = toPK.getTable();
530:                if (_pkTable != null && !_pkTable.equals(pkTable))
531:                    throw new InvalidStateException(_loc.get("fk-mismatch",
532:                            pkTable, _pkTable));
533:
534:                _pkTable = pkTable;
535:                if (_joins == null)
536:                    _joins = new LinkedHashMap();
537:                _joins.put(local, toPK);
538:                if (_joinsPK == null)
539:                    _joinsPK = new LinkedHashMap();
540:                _joinsPK.put(toPK, local);
541:
542:                // force re-cache
543:                _locals = null;
544:                _pks = null;
545:                if (_autoAssign == Boolean.FALSE)
546:                    _autoAssign = null;
547:            }
548:
549:            /**
550:             * Join a constant value to a primary key column of another table. The
551:             * constant must be either a string or a number.
552:             */
553:            public void joinConstant(Object val, Column toPK) {
554:                Table pkTable = toPK.getTable();
555:                if (_pkTable != null && !_pkTable.equals(pkTable))
556:                    throw new InvalidStateException(_loc.get("fk-mismatch",
557:                            pkTable, _pkTable));
558:
559:                _pkTable = pkTable;
560:                if (_constsPK == null)
561:                    _constsPK = new LinkedHashMap();
562:                _constsPK.put(toPK, val);
563:
564:                // force re-cache
565:                _constValsPK = null;
566:                _constColsPK = null;
567:            }
568:
569:            /**
570:             * Join a constant value to a local column of this table. The
571:             * constant must be either a string or a number.
572:             */
573:            public void joinConstant(Column col, Object val) {
574:                if (_consts == null)
575:                    _consts = new LinkedHashMap();
576:                _consts.put(col, val);
577:
578:                // force re-cache
579:                _constVals = null;
580:                _constCols = null;
581:            }
582:
583:            /**
584:             * Remove any joins inolving the given column.
585:             *
586:             * @return true if the join was removed, false if not part of the key
587:             */
588:            public boolean removeJoin(Column col) {
589:                boolean remd = false;
590:                Object rem;
591:
592:                if (_joins != null) {
593:                    rem = _joins.remove(col);
594:                    if (rem != null) {
595:                        _locals = null;
596:                        _pks = null;
597:                        _joinsPK.remove(rem);
598:                        remd = true;
599:                    }
600:                }
601:
602:                if (_joinsPK != null) {
603:                    rem = _joinsPK.remove(col);
604:                    if (rem != null) {
605:                        _locals = null;
606:                        _pks = null;
607:                        _joins.remove(rem);
608:                        remd = true;
609:                    }
610:                }
611:
612:                if (_consts != null) {
613:                    if (_consts.remove(col) != null) {
614:                        _constVals = null;
615:                        _constCols = null;
616:                        remd = true;
617:                    }
618:                }
619:
620:                if (_constsPK != null) {
621:                    if (_constsPK.containsKey(col)) {
622:                        _constsPK.remove(col);
623:                        _constValsPK = null;
624:                        _constColsPK = null;
625:                        remd = true;
626:                    }
627:                }
628:
629:                if ((_joins == null || _joins.isEmpty())
630:                        && (_constsPK == null || _constsPK.isEmpty()))
631:                    _pkTable = null;
632:                if (remd && _autoAssign == Boolean.TRUE)
633:                    _autoAssign = null;
634:                return remd;
635:            }
636:
637:            /**
638:             * Returns the table this foreign key is linking to, if it is known yet.
639:             */
640:            public Table getPrimaryKeyTable() {
641:                return _pkTable;
642:            }
643:
644:            /**
645:             * Ref all columns in this key.
646:             */
647:            public void refColumns() {
648:                Column[] cols = getColumns();
649:                for (int i = 0; i < cols.length; i++)
650:                    cols[i].ref();
651:                cols = getConstantColumns();
652:                for (int i = 0; i < cols.length; i++)
653:                    cols[i].ref();
654:            }
655:
656:            /**
657:             * Deref all columns in this key.
658:             */
659:            public void derefColumns() {
660:                Column[] cols = getColumns();
661:                for (int i = 0; i < cols.length; i++)
662:                    cols[i].deref();
663:                cols = getConstantColumns();
664:                for (int i = 0; i < cols.length; i++)
665:                    cols[i].deref();
666:            }
667:
668:            /**
669:             * Foreign keys are equal if the satisfy the equality constraints of
670:             * {@link Constraint} and they have the same local and primary key
671:             * columns and action.
672:             */
673:            public boolean equalsForeignKey(ForeignKey fk) {
674:                if (fk == this )
675:                    return true;
676:                if (fk == null)
677:                    return false;
678:
679:                if (getDeleteAction() != fk.getDeleteAction())
680:                    return false;
681:                if (isDeferred() != fk.isDeferred())
682:                    return false;
683:
684:                if (!columnsMatch(fk.getColumns(), fk.getPrimaryKeyColumns()))
685:                    return false;
686:                if (!match(getConstantColumns(), fk.getConstantColumns()))
687:                    return false;
688:                if (!match(getConstants(), fk.getConstants()))
689:                    return false;
690:                if (!match(getConstantPrimaryKeyColumns(), fk
691:                        .getConstantPrimaryKeyColumns()))
692:                    return false;
693:                if (!match(getPrimaryKeyConstants(), fk
694:                        .getPrimaryKeyConstants()))
695:                    return false;
696:                return true;
697:            }
698:
699:            /**
700:             * Return true if the given local and foreign columns match those
701:             * on this key. This can be used to find foreign keys given only
702:             * column linking information.
703:             */
704:            public boolean columnsMatch(Column[] fkCols, Column[] fkPKCols) {
705:                return match(getColumns(), fkCols)
706:                        && match(getPrimaryKeyColumns(), fkPKCols);
707:            }
708:
709:            /**
710:             * Checks for non-nullable local columns.
711:             */
712:            public boolean hasNotNullColumns() {
713:                Column[] columns = getColumns();
714:                for (int j = 0; j < columns.length; j++) {
715:                    if (columns[j].isNotNull()) {
716:                        return true;
717:                    }
718:                }
719:                return false;
720:            }
721:
722:            private static boolean match(Column[] cols, Column[] fkCols) {
723:                if (cols.length != fkCols.length)
724:                    return false;
725:                for (int i = 0; i < fkCols.length; i++)
726:                    if (!hasColumn(cols, fkCols[i]))
727:                        return false;
728:                return true;
729:            }
730:
731:            private static boolean hasColumn(Column[] cols, Column col) {
732:                for (int i = 0; i < cols.length; i++)
733:                    if (cols[i].getFullName().equalsIgnoreCase(
734:                            col.getFullName()))
735:                        return true;
736:                return false;
737:            }
738:
739:            private static boolean match(Object[] vals, Object[] fkVals) {
740:                if (vals.length != fkVals.length)
741:                    return false;
742:                for (int i = 0; i < vals.length; i++)
743:                    if (!ObjectUtils.equals(vals[i], fkVals[i]))
744:                        return false;
745:                return true;
746:            }
747:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.