Source Code Cross Referenced for OrdinalManager.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » cmf » dam » 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 » Web Framework » rife 1.6.1 » com.uwyn.rife.cmf.dam 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003:         * Distributed under the terms of either:
004:         * - the common development and distribution license (CDDL), v1.0; or
005:         * - the GNU Lesser General Public License, v2.1 or later
006:         * $Id: OrdinalManager.java 3634 2007-01-08 21:42:24Z gbevin $
007:         */
008:        package com.uwyn.rife.cmf.dam;
009:
010:        import com.uwyn.rife.database.*;
011:
012:        import com.uwyn.rife.database.queries.Select;
013:        import com.uwyn.rife.database.queries.Update;
014:        import com.uwyn.rife.datastructures.EnumClass;
015:        import com.uwyn.rife.tools.ExceptionUtils;
016:        import com.uwyn.rife.tools.InnerClassException;
017:        import java.sql.SQLException;
018:        import java.util.logging.Logger;
019:
020:        /**
021:         * This class makes it possible to easily manage an integer ordinal column
022:         * that is typically used to determine the order of the rows in a specific
023:         * table.
024:         * <p>The basic version manages the ordinals for the entire table, but it's
025:         * also possible to create an <code>OrdinalManager</code> that uses several
026:         * independent ranges of ordinals according to a restricting integer column.
027:         * <p>For example, consider the following '<code>article</code>' table:
028:         * <pre>id          INT
029:         *categoryId  INT
030:         *ordinal     INT
031:         *name        VARCHAR(30)</pre>
032:         * <p>with the following rows:
033:         * <pre> id | categoryId | ordinal | name
034:         *----+------------+---------+-----------------------
035:         *  2 |          1 |       0 | some article
036:         *  0 |          1 |       1 | another one
037:         *  3 |          1 |       2 | boom boom
038:         *  1 |          2 |       0 | this is yet an article
039:         *  5 |          2 |       1 | an article for you
040:         *  4 |          3 |       0 | our latest article
041:         *  6 |          3 |       1 | important one</pre>
042:         * <p>You can clearly see three independent <code>ordinal</code> ranges
043:         * according to the <code>categoryId</code> column.
044:         * <p>The <code>OrdinalManager</code> allows you to easily change the order of
045:         * the articles by moving them up and down with the provided methods: {@link
046:         * #move(Direction, int) move}, {@link #up(int) up} and {@link #down(int) down}.
047:         * It's also possible to do more complex manipulations by using the lower
048:         * level methods: {@link #free(int) free}, {@link #update(int, int) update},
049:         * {@link #tighten() tighten} and {@link #obtainInsertOrdinal()
050:         * obtainInsertOrdinal}.
051:         *
052:         * @author Geert Bevin (gbevin[remove] at uwyn dot com)
053:         * @version $Revision: 3634 $
054:         * @since 1.0
055:         */
056:        public class OrdinalManager implements  Cloneable {
057:            /**
058:             * Has to be used to indicate an upwards direction for the {@link
059:             * #move(Direction, int) move} method.
060:             */
061:            public static final Direction UP = new Direction("up");
062:            /**
063:             * Has to be used to indicate an downwards direction for the {@link
064:             * #move(Direction, int) move} method.
065:             */
066:            public static final Direction DOWN = new Direction("down");
067:
068:            private Datasource mDatasource = null;
069:            private DbQueryManager mDbQueryManager = null;
070:            private String mTable = null;
071:            private String mOrdinalColumn = null;
072:            private String mRestrictColumn = null;
073:            private Update mFreeMoveOrdinal = null;
074:            private Select mGetFinalOrdinal = null;
075:            private Select mGetOrdinals = null;
076:            private Select mGetFinalOrdinalRestricted = null;
077:            private Update mFreeMoveOrdinalRestricted = null;
078:            private Select mGetOrdinalsRestricted = null;
079:
080:            /**
081:             * Creates a new <code>OrdinalManager</code> that manages ordinals
082:             * globally for the specified table.
083:             *
084:             * @param datasource the datasource where the table is accessible
085:             * @param table the name of the table that will be managed
086:             * @param ordinalColumn the name of the column that contains the integer
087:             * ordinals
088:             * @since 1.0
089:             */
090:            public OrdinalManager(Datasource datasource, String table,
091:                    String ordinalColumn) {
092:                if (null == datasource)
093:                    throw new IllegalArgumentException(
094:                            "datasource can't be null");
095:                if (null == table)
096:                    throw new IllegalArgumentException("table can't be null");
097:                if (null == ordinalColumn)
098:                    throw new IllegalArgumentException(
099:                            "ordinalColumn can't be null");
100:
101:                mDatasource = datasource;
102:
103:                mDbQueryManager = new DbQueryManager(datasource);
104:
105:                mTable = table;
106:                mOrdinalColumn = ordinalColumn;
107:
108:                mGetFinalOrdinal = new Select(datasource);
109:                mGetFinalOrdinal.field(mOrdinalColumn).from(mTable).orderBy(
110:                        mOrdinalColumn, Select.DESC);
111:
112:                mFreeMoveOrdinal = new Update(datasource);
113:                mFreeMoveOrdinal.table(mTable).whereParameter(mOrdinalColumn,
114:                        "current", "=").fieldParameter(mOrdinalColumn, "new");
115:
116:                mGetOrdinals = new Select(datasource);
117:                mGetOrdinals.field(mOrdinalColumn).from(mTable).orderBy(
118:                        mOrdinalColumn, Select.ASC);
119:            }
120:
121:            /**
122:             * Creates a new <code>OrdinalManager</code> that manages ordinals for the
123:             * specified table in independent ranges according to a restricting
124:             * integer column.
125:             *
126:             * @param datasource the datasource where the table is accessible
127:             * @param table the name of the table that will be managed
128:             * @param ordinalColumn the name of the column that contains the integer
129:             * ordinals
130:             * @param restrictColumn the name of the column whose values will
131:             * partition the ordinals in independent ranges
132:             * @since 1.0
133:             */
134:            public OrdinalManager(Datasource datasource, String table,
135:                    String ordinalColumn, String restrictColumn) {
136:                this (datasource, table, ordinalColumn);
137:
138:                if (null == restrictColumn)
139:                    throw new IllegalArgumentException(
140:                            "restrictColumn can't be null");
141:
142:                mRestrictColumn = restrictColumn;
143:
144:                mGetFinalOrdinalRestricted = new Select(mDatasource);
145:                mGetFinalOrdinalRestricted.field(mOrdinalColumn).from(mTable)
146:                        .whereParameter(mRestrictColumn, "=").orderBy(
147:                                mOrdinalColumn, Select.DESC);
148:
149:                mFreeMoveOrdinalRestricted = new Update(mDatasource);
150:                mFreeMoveOrdinalRestricted.table(mTable).whereParameter(
151:                        mRestrictColumn, "=").whereParameterAnd(mOrdinalColumn,
152:                        "current", "=").fieldParameter(mOrdinalColumn, "new");
153:
154:                mGetOrdinalsRestricted = new Select(mDatasource);
155:                mGetOrdinalsRestricted.field(mOrdinalColumn).from(mTable)
156:                        .whereParameter(mRestrictColumn, "=").orderBy(
157:                                mOrdinalColumn, Select.ASC);
158:
159:            }
160:
161:            /**
162:             * Retrieves the name of the table of this <code>OrdinalManager</code>.
163:             *
164:             * @return the name of the table
165:             * @since 1.0
166:             */
167:            public String getTable() {
168:                return mTable;
169:            }
170:
171:            /**
172:             * Retrieves the name of the ordinal column.
173:             *
174:             * @return the name of the ordinal column
175:             * @since 1.0
176:             */
177:            public String getOrdinalColumn() {
178:                return mOrdinalColumn;
179:            }
180:
181:            /**
182:             * Retrieves the name of the restricting column.
183:             *
184:             * @return the name of the restricting column; or
185:             * <p><code>null</code> if this <code>OrdinalManager</code> manages the
186:             * table globally
187:             * @since 1.0
188:             */
189:            public String getRestrictColumn() {
190:                return mRestrictColumn;
191:            }
192:
193:            /**
194:             * Moves the position of a row with a specific ordinal within the entire
195:             * table.
196:             *
197:             * @param direction the direction in which to move: {@link
198:             * OrdinalManager#UP OrdinalManager.UP} or {@link OrdinalManager#DOWN
199:             * OrdinalManager.DOWN}
200:             * @param ordinal the ordinal of the row that has to be moved
201:             * @return <code>true</code> if the move was executed successfully; or
202:             * <p><code>false</code> if this wasn't the case
203:             * @see #move(Direction, long, int)
204:             * @since 1.0
205:             */
206:            public boolean move(Direction direction, final int ordinal) {
207:                if (direction == UP) {
208:                    return up(ordinal);
209:                } else if (direction == DOWN) {
210:                    return down(ordinal);
211:                }
212:
213:                return false;
214:            }
215:
216:            /**
217:             * Moves the position of a row with a specific ordinal within the range
218:             * restricted by the provided ID.
219:             *
220:             * @param direction the direction in which to move: {@link
221:             * OrdinalManager#UP OrdinalManager.UP} or {@link OrdinalManager#DOWN
222:             * OrdinalManager.DOWN}
223:             * @param restrictId the restriction ID value
224:             * @param ordinal the ordinal of the row that has to be moved
225:             * @return <code>true</code> if the move was executed successfully; or
226:             * <p><code>false</code> if this wasn't the case
227:             * @see #move(Direction, int)
228:             * @since 1.0
229:             */
230:            public boolean move(Direction direction, final long restrictId,
231:                    final int ordinal) {
232:                if (direction == UP) {
233:                    return up(restrictId, ordinal);
234:                } else if (direction == DOWN) {
235:                    return down(restrictId, ordinal);
236:                }
237:
238:                return false;
239:            }
240:
241:            /**
242:             * Moves a row with a specific ordinal upwards within the entire table.
243:             *
244:             * @param ordinal the ordinal of the row that has to be moved
245:             * @return <code>true</code> if the move was executed successfully; or
246:             * <p><code>false</code> if this wasn't the case
247:             * @see #up(long, int)
248:             * @since 1.0
249:             */
250:            public boolean up(final int ordinal) {
251:                Boolean result = mDbQueryManager
252:                        .inTransaction(new DbTransactionUser() {
253:                            public Boolean useTransaction()
254:                                    throws InnerClassException {
255:                                if (!free(ordinal - 1)) {
256:                                    rollback();
257:                                }
258:                                if (!update(ordinal + 1, ordinal - 1)) {
259:                                    rollback();
260:                                }
261:                                if (!tighten()) {
262:                                    rollback();
263:                                }
264:
265:                                return true;
266:                            }
267:                        });
268:
269:                return null != result && result.booleanValue();
270:            }
271:
272:            /**
273:             * Moves a row with a specific ordinal upwards within the range restricted
274:             * by the provided ID.
275:             *
276:             * @param restrictId the restriction ID value
277:             * @param ordinal the ordinal of the row that has to be moved
278:             * @return <code>true</code> if the move was executed successfully; or
279:             * <p><code>false</code> if this wasn't the case
280:             * @see #up(int)
281:             * @since 1.0
282:             */
283:            public boolean up(final long restrictId, final int ordinal) {
284:                Boolean result = mDbQueryManager
285:                        .inTransaction(new DbTransactionUser() {
286:                            public Boolean useTransaction()
287:                                    throws InnerClassException {
288:                                if (!free(restrictId, ordinal - 1)) {
289:                                    rollback();
290:                                }
291:                                if (!update(restrictId, ordinal + 1,
292:                                        ordinal - 1)) {
293:                                    rollback();
294:                                }
295:                                if (!tighten(restrictId)) {
296:                                    rollback();
297:                                }
298:
299:                                return true;
300:                            }
301:                        });
302:
303:                return null != result && result.booleanValue();
304:            }
305:
306:            /**
307:             * Moves a row with a specific ordinal downwards within the entire table.
308:             *
309:             * @param ordinal the ordinal of the row that has to be moved
310:             * @return <code>true</code> if the move was executed successfully; or
311:             * <p><code>false</code> if this wasn't the case
312:             * @see #down(long, int)
313:             * @since 1.0
314:             */
315:            public boolean down(final int ordinal) {
316:                Boolean result = mDbQueryManager
317:                        .inTransaction(new DbTransactionUser() {
318:                            public Boolean useTransaction()
319:                                    throws InnerClassException {
320:                                if (!free(ordinal + 2)) {
321:                                    rollback();
322:                                }
323:                                if (!update(ordinal, ordinal + 2)) {
324:                                    rollback();
325:                                }
326:                                if (!tighten()) {
327:                                    rollback();
328:                                }
329:
330:                                return true;
331:                            }
332:                        });
333:
334:                return null != result && result.booleanValue();
335:            }
336:
337:            /**
338:             * Moves a row with a specific ordinal downwards within the range
339:             * restricted by the provided ID.
340:             *
341:             * @param restrictId the restriction ID value
342:             * @param ordinal the ordinal of the row that has to be moved
343:             * @return <code>true</code> if the move was executed successfully; or
344:             * <p><code>false</code> if this wasn't the case
345:             * @see #down(int)
346:             * @since 1.0
347:             */
348:            public boolean down(final long restrictId, final int ordinal) {
349:                Boolean result = mDbQueryManager
350:                        .inTransaction(new DbTransactionUser() {
351:                            public Boolean useTransaction()
352:                                    throws InnerClassException {
353:                                if (!free(restrictId, ordinal + 2)) {
354:                                    rollback();
355:                                }
356:                                if (!update(restrictId, ordinal, ordinal + 2)) {
357:                                    rollback();
358:                                }
359:                                if (!tighten(restrictId)) {
360:                                    rollback();
361:                                }
362:
363:                                return true;
364:                            }
365:                        });
366:
367:                return null != result && result.booleanValue();
368:            }
369:
370:            /**
371:             * Moves a row with a specific ordinal to the location of another ordinal
372:             * within the entire table.
373:             *
374:             * @param fromOrdinal the ordinal of the row that has to be moved
375:             * @param toOrdinal the ordinal of the row where the from row has will be
376:             * put above
377:             * @return <code>true</code> if the move was executed successfully; or
378:             * <p><code>false</code> if this wasn't the case
379:             * @see #down(int)
380:             * @since 1.0
381:             */
382:            public boolean move(final int fromOrdinal, final int toOrdinal) {
383:                Boolean result = mDbQueryManager
384:                        .inTransaction(new DbTransactionUser() {
385:                            public Boolean useTransaction()
386:                                    throws InnerClassException {
387:                                if (!free(toOrdinal)) {
388:                                    rollback();
389:                                }
390:                                int real_from = fromOrdinal;
391:                                if (toOrdinal < fromOrdinal) {
392:                                    real_from++;
393:                                }
394:                                if (!update(real_from, toOrdinal)) {
395:                                    rollback();
396:                                }
397:                                if (!tighten()) {
398:                                    rollback();
399:                                }
400:
401:                                return true;
402:                            }
403:                        });
404:
405:                return null != result && result.booleanValue();
406:            }
407:
408:            /**
409:             * Moves a row with a specific ordinal to the location of another ordinal
410:             * within the range restricted by the provided ID.
411:             *
412:             * @param restrictId the restriction ID value
413:             * @param fromOrdinal the ordinal of the row that has to be moved
414:             * @param toOrdinal the ordinal of the row where the from row has will be
415:             * put above
416:             * @return <code>true</code> if the move was executed successfully; or
417:             * <p><code>false</code> if this wasn't the case
418:             * @see #down(int)
419:             * @since 1.0
420:             */
421:            public boolean move(final long restrictId, final int fromOrdinal,
422:                    final int toOrdinal) {
423:                if (fromOrdinal == toOrdinal) {
424:                    return true;
425:                }
426:
427:                Boolean result = mDbQueryManager
428:                        .inTransaction(new DbTransactionUser() {
429:                            public Boolean useTransaction()
430:                                    throws InnerClassException {
431:                                if (!free(restrictId, toOrdinal)) {
432:                                    rollback();
433:                                }
434:                                int real_from = fromOrdinal;
435:                                if (toOrdinal < fromOrdinal) {
436:                                    real_from++;
437:                                }
438:                                if (!update(restrictId, real_from, toOrdinal)) {
439:                                    rollback();
440:                                }
441:                                if (!tighten(restrictId)) {
442:                                    rollback();
443:                                }
444:
445:                                return true;
446:                            }
447:                        });
448:
449:                return null != result && result.booleanValue();
450:            }
451:
452:            /**
453:             * Frees up a slot for the specified ordinal within the entire table.,
454:             * this is done by incrementing everything after it by 1 to make space.
455:             * <p>So for example issuing the method <code>free(1)</code> on the
456:             * following table:
457:             * <pre> id | ordinal | name
458:             *----+---------+-----------------------
459:             *  2 |       0 | some article
460:             *  0 |       1 | another one
461:             *  1 |       2 | this is yet an article</pre>
462:             * <p>will result in:
463:             * <pre> id | ordinal | name
464:             *----+---------+-----------------------
465:             *  2 |       0 | some article
466:             *  0 |       2 | another one
467:             *  1 |       3 | this is yet an article</pre>
468:             *
469:             * @param ordinal an integer representing the ordinal to free
470:             * @return <code>true</code> if the slot was freed up correctly; or
471:             * <p><code>false</code> if the operation wasn't possible
472:             * @see #free(long, int)
473:             * @since 1.0
474:             */
475:            public boolean free(final int ordinal) {
476:                Boolean result = mDbQueryManager
477:                        .inTransaction(new DbTransactionUser() {
478:                            public Boolean useTransaction()
479:                                    throws InnerClassException {
480:                                if (ordinal < 0) {
481:                                    return false;
482:                                }
483:
484:                                int last_ordinal = mDbQueryManager
485:                                        .executeGetFirstInt(mGetFinalOrdinal);
486:
487:                                for (int i = last_ordinal; i >= ordinal; i--) {
488:                                    final int current_ordinal = i;
489:
490:                                    mDbQueryManager.executeUpdate(
491:                                            mFreeMoveOrdinal,
492:                                            new DbPreparedStatementHandler() {
493:                                                public void setParameters(
494:                                                        DbPreparedStatement statement) {
495:                                                    statement
496:                                                            .setInt("current",
497:                                                                    current_ordinal)
498:                                                            .setInt(
499:                                                                    "new",
500:                                                                    current_ordinal + 1);
501:                                                }
502:                                            });
503:                                }
504:
505:                                return true;
506:                            }
507:                        });
508:
509:                return null != result && result.booleanValue();
510:            }
511:
512:            /**
513:             * Frees up a slot for the specified ordinal within the range restricted
514:             * by the provided ID, this is done by incrementing everything after it by
515:             * 1 to make space.
516:             * <p>So for example issuing the method <code>free(2, 0)</code> on the
517:             * following table:
518:             * <pre> id | categoryId | ordinal | name
519:             *----+------------+---------+-----------------------
520:             *  2 |          1 |       0 | some article
521:             *  0 |          1 |       1 | another one
522:             *  3 |          1 |       2 | boom boom
523:             *  1 |          2 |       0 | this is yet an article
524:             *  5 |          2 |       1 | an article for you
525:             *  4 |          3 |       0 | our latest article
526:             *  6 |          3 |       1 | important one</pre>
527:             * <p>will result into:
528:             * <pre> id | categoryId | ordinal | name
529:             *----+------------+---------+-----------------------
530:             *  2 |          1 |       0 | some article
531:             *  0 |          1 |       1 | another one
532:             *  3 |          1 |       2 | boom boom
533:             *  1 |          2 |       1 | this is yet an article
534:             *  5 |          2 |       2 | an article for you
535:             *  4 |          3 |       0 | our latest article
536:             *  6 |          3 |       1 | important one</pre>
537:             *
538:             * @param restrictId the id by which to restrict with
539:             * @param ordinal an int representation the ordinal to free
540:             * @return <code>true</code> if the slot was freed up correctly; or
541:             * <p><code>false</code> if the operation wasn't possible
542:             * @see #free(int)
543:             * @since 1.0
544:             */
545:            public boolean free(final long restrictId, final int ordinal) {
546:                Boolean result = mDbQueryManager
547:                        .inTransaction(new DbTransactionUser() {
548:                            public Boolean useTransaction()
549:                                    throws InnerClassException {
550:                                if (ordinal < 0) {
551:                                    return false;
552:                                }
553:
554:                                int last_ordinal = mDbQueryManager
555:                                        .executeGetFirstInt(
556:                                                mGetFinalOrdinalRestricted,
557:                                                new DbPreparedStatementHandler() {
558:                                                    public void setParameters(
559:                                                            DbPreparedStatement statement) {
560:                                                        statement
561:                                                                .setLong(
562:                                                                        mRestrictColumn,
563:                                                                        restrictId);
564:                                                    }
565:                                                });
566:
567:                                for (int i = last_ordinal; i >= ordinal; i--) {
568:                                    final int current_ordinal = i;
569:
570:                                    mDbQueryManager.executeUpdate(
571:                                            mFreeMoveOrdinalRestricted,
572:                                            new DbPreparedStatementHandler() {
573:                                                public void setParameters(
574:                                                        DbPreparedStatement statement) {
575:                                                    statement
576:                                                            .setLong(
577:                                                                    mRestrictColumn,
578:                                                                    restrictId)
579:                                                            .setInt("current",
580:                                                                    current_ordinal)
581:                                                            .setInt(
582:                                                                    "new",
583:                                                                    current_ordinal + 1);
584:                                                }
585:                                            });
586:                                }
587:
588:                                return true;
589:                            }
590:                        });
591:
592:                return null != result && result.booleanValue();
593:            }
594:
595:            /**
596:             * Changes the ordinal of a certain row to a new value.
597:             * <p>This simply updates the value of the ordinal column and doesn't
598:             * execute any other logic.
599:             *
600:             * @param currentOrdinal the ordinal of the row that has to be updated
601:             * @param newOrdinal the new ordinal value
602:             * @return <code>true</code> if the update was executed successfully; or
603:             * <p><code>false</code> if this wasn't the case
604:             * @see #update(long, int, int)
605:             * @since 1.0
606:             */
607:            public boolean update(final int currentOrdinal, final int newOrdinal) {
608:                Boolean result = mDbQueryManager
609:                        .inTransaction(new DbTransactionUser() {
610:                            public Boolean useTransaction()
611:                                    throws InnerClassException {
612:                                return 0 != mDbQueryManager.executeUpdate(
613:                                        mFreeMoveOrdinal,
614:                                        new DbPreparedStatementHandler() {
615:                                            public void setParameters(
616:                                                    DbPreparedStatement statement) {
617:                                                statement.setInt("current",
618:                                                        currentOrdinal).setInt(
619:                                                        "new", newOrdinal);
620:                                            }
621:                                        });
622:
623:                            }
624:                        });
625:
626:                return null != result && result.booleanValue();
627:            }
628:
629:            /**
630:             * Changes the ordinal of a certain row with a specific restriction ID to
631:             * a new value.
632:             * <p>This simply updates the value of the ordinal column and doesn't
633:             * execute any other logic.
634:             *
635:             * @param restrictId the id by which to restrict with
636:             * @param currentOrdinal the ordinal of the row that has to be updated
637:             * @param newOrdinal the new ordinal value
638:             * @return <code>true</code> if the update was executed successfully; or
639:             * <p><code>false</code> if this wasn't the case
640:             * @see #update(int, int)
641:             * @since 1.0
642:             */
643:            public boolean update(final long restrictId,
644:                    final int currentOrdinal, final int newOrdinal) {
645:                Boolean result = mDbQueryManager
646:                        .inTransaction(new DbTransactionUser() {
647:                            public Boolean useTransaction()
648:                                    throws InnerClassException {
649:                                return 0 != mDbQueryManager.executeUpdate(
650:                                        mFreeMoveOrdinalRestricted,
651:                                        new DbPreparedStatementHandler() {
652:                                            public void setParameters(
653:                                                    DbPreparedStatement statement) {
654:                                                statement.setLong(
655:                                                        mRestrictColumn,
656:                                                        restrictId).setInt(
657:                                                        "current",
658:                                                        currentOrdinal).setInt(
659:                                                        "new", newOrdinal);
660:                                            }
661:                                        });
662:
663:                            }
664:                        });
665:
666:                return null != result && result.booleanValue();
667:            }
668:
669:            /**
670:             * Tightens the series of ordinal within the entire table so that no
671:             * spaces are present in between the ordinals.
672:             * <p>So for example issuing the method <code>tighten()</code> on the
673:             * following table:
674:             * <pre> id | ordinal | name
675:             *----+---------+-----------------------
676:             *  2 |       0 | some article
677:             *  0 |       2 | another one
678:             *  1 |       5 | this is yet an article</pre>
679:             * <p>will result in:
680:             * <pre> id | ordinal | name
681:             *----+---------+-----------------------
682:             *  2 |       0 | some article
683:             *  0 |       1 | another one
684:             *  1 |       2 | this is yet an article</pre>
685:             *
686:             * @return <code>true</code> if the tightening was executed correctly; or
687:             * <p><code>false</code> if the operation wasn't possible
688:             * @see #tighten(long)
689:             * @since 1.0
690:             */
691:            public boolean tighten() {
692:                mDbQueryManager
693:                        .inTransaction(new DbTransactionUserWithoutResult() {
694:                            public void useTransactionWithoutResult()
695:                                    throws InnerClassException {
696:                                mDbQueryManager.executeQuery(mGetOrdinals,
697:                                        new TightenResultSetHandler());
698:                            }
699:                        });
700:
701:                return true;
702:            }
703:
704:            /**
705:             * Tightens the series of ordinal within the range restricted by the
706:             * provided ID so that no spaces are present in between the ordinals.
707:             * <p>So for example issuing the method <code>tighten(2)</code> on the
708:             * following table:
709:             * <pre> id | categoryId | ordinal | name
710:             *----+------------+---------+-----------------------
711:             *  2 |          1 |       1 | some article
712:             *  0 |          1 |       2 | another one
713:             *  3 |          1 |       7 | boom boom
714:             *  1 |          2 |       4 | this is yet an article
715:             *  5 |          2 |       8 | an article for you
716:             *  4 |          3 |       4 | our latest article
717:             *  6 |          3 |       5 | important one</pre>
718:             * <p>will result in:
719:             * <pre> id | categoryId | ordinal | name
720:             *----+------------+---------+-----------------------
721:             *  2 |          1 |       1 | some article
722:             *  0 |          1 |       2 | another one
723:             *  3 |          1 |       7 | boom boom
724:             *  1 |          2 |       0 | this is yet an article
725:             *  5 |          2 |       1 | an article for you
726:             *  4 |          3 |       4 | our latest article
727:             *  6 |          3 |       5 | important one</pre>
728:             *
729:             * @param restrictId the id by which to restrict with
730:             * @return <code>true</code> if the tightening was executed correctly; or
731:             * <p><code>false</code> if the operation wasn't possible
732:             * @see #tighten()
733:             * @since 1.0
734:             */
735:            public boolean tighten(final long restrictId) {
736:                final TightenResultSetHandlerRestricted handler = new TightenResultSetHandlerRestricted(
737:                        restrictId) {
738:                    public void setParameters(DbPreparedStatement statement) {
739:                        statement.setLong(mRestrictColumn, restrictId);
740:                    }
741:                };
742:
743:                mDbQueryManager
744:                        .inTransaction(new DbTransactionUserWithoutResult() {
745:                            public void useTransactionWithoutResult()
746:                                    throws InnerClassException {
747:                                mDbQueryManager.executeQuery(
748:                                        mGetOrdinalsRestricted, handler);
749:                            }
750:                        });
751:
752:                return handler.isTightened();
753:            }
754:
755:            /**
756:             * Returns the next freely available ordinal that can be used to insert a
757:             * new row behind all the other rows in the entire table.
758:             * <p>So for example issuing the method <code>obtainInsertOrdinal()</code>
759:             * on the following table:
760:             * <pre> id | ordinal | name
761:             *----+---------+-----------------------
762:             *  2 |       0 | some article
763:             *  0 |       1 | another one
764:             *  1 |       2 | this is yet an article</pre>
765:             * <p>Will return the value <code>3</code>.
766:             *
767:             * @return the requested ordinal; or
768:             * <p><code>0</code> if no ordinals are present within the table yet
769:             * @see #obtainInsertOrdinal(long)
770:             * @since 1.0
771:             */
772:            public int obtainInsertOrdinal() {
773:                // return next ordinal to use
774:                // +1 because mGetFinalOrdinal returns the last ordinal
775:                // in the db series
776:                return mDbQueryManager.executeGetFirstInt(mGetFinalOrdinal) + 1;
777:            }
778:
779:            /**
780:             * Returns the next freely available ordinal that can be used to insert a
781:             * new row behind all the other rows in the range restricted by the
782:             * provided ID.
783:             * <p>So for example issuing the method
784:             * <code>obtainInsertOrdinal(3)</code> on the following table:
785:             * <pre> id | categoryId | ordinal | name
786:             *----+------------+---------+-----------------------
787:             *  2 |          1 |       0 | some article
788:             *  0 |          1 |       1 | another one
789:             *  3 |          1 |       2 | boom boom
790:             *  1 |          2 |       0 | this is yet an article
791:             *  5 |          2 |       1 | an article for you
792:             *  4 |          3 |       0 | our latest article
793:             *  6 |          3 |       1 | important one</pre>
794:             * <p>Will return the value <code>2</code>.
795:             *
796:             * @param restrictId the id by which to restrict with
797:             * @return the requested ordinal; or
798:             * <p><code>0</code> if no ordinals are present within the range yet
799:             * @see #obtainInsertOrdinal()
800:             * @since 1.0
801:             */
802:            public int obtainInsertOrdinal(final long restrictId) {
803:                // return next ordinal to use
804:                int ordinal = mDbQueryManager.executeGetFirstInt(
805:                        mGetFinalOrdinalRestricted,
806:                        new DbPreparedStatementHandler() {
807:                            public void setParameters(
808:                                    DbPreparedStatement statement) {
809:                                statement.setLong(mRestrictColumn, restrictId);
810:                            }
811:                        });
812:
813:                return ordinal + 1;
814:            }
815:
816:            /**
817:             * Simply clones the instance with the default clone method. This creates
818:             * a shallow copy of all fields and the clone will in fact just be another
819:             * reference to the same underlying data. The independence of each cloned
820:             * instance is consciously not respected since they rely on resources that
821:             * can't be cloned.
822:             *
823:             * @since 1.0
824:             */
825:            public Object clone() {
826:                try {
827:                    return super .clone();
828:                } catch (CloneNotSupportedException e) {
829:                    ///CLOVER:OFF
830:                    // this should never happen
831:                    Logger.getLogger("com.uwyn.rife.cmf").severe(
832:                            ExceptionUtils.getExceptionStackTrace(e));
833:                    return null;
834:                    ///CLOVER:ON
835:                }
836:            }
837:
838:            private class TightenResultSetHandler extends
839:                    DbPreparedStatementHandler {
840:                private int mCount = 0;
841:
842:                public TightenResultSetHandler() {
843:                }
844:
845:                public Object concludeResults(DbResultSet resultset)
846:                        throws SQLException {
847:                    while (resultset.next()) {
848:                        int ordinal = resultset.getInt(mOrdinalColumn);
849:                        if (ordinal != mCount) {
850:                            update(ordinal, mCount);
851:                        }
852:                        mCount++;
853:                    }
854:
855:                    return null;
856:                }
857:            }
858:
859:            private class TightenResultSetHandlerRestricted extends
860:                    DbPreparedStatementHandler {
861:                private int mCount = 0;
862:                private long mRestrictId = -1;
863:
864:                private boolean mTightened = false;
865:
866:                public TightenResultSetHandlerRestricted(long restrictId) {
867:                    mRestrictId = restrictId;
868:                }
869:
870:                public Object concludeResults(DbResultSet resultset)
871:                        throws SQLException {
872:                    while (resultset.next()) {
873:                        mTightened = true;
874:
875:                        int ordinal = resultset.getInt(mOrdinalColumn);
876:                        if (ordinal != mCount) {
877:                            update(mRestrictId, ordinal, mCount);
878:                        }
879:                        mCount++;
880:                    }
881:
882:                    return null;
883:                }
884:
885:                public boolean isTightened() {
886:                    return mTightened;
887:                }
888:            }
889:
890:            public static class Direction extends EnumClass<String> {
891:                private Direction(String identifier) {
892:                    super (identifier);
893:                }
894:
895:                public static Direction getDirection(String name) {
896:                    return getMember(Direction.class, name);
897:                }
898:            }
899:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.