Source Code Cross Referenced for ContentList.java in  » XML » jdom » org » jdom » 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 » XML » jdom » org.jdom 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*--
0002:
0003:         $Id: ContentList.java,v 1.39 2004/02/28 03:30:27 jhunter Exp $
0004:
0005:         Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
0006:         All rights reserved.
0007:
0008:         Redistribution and use in source and binary forms, with or without
0009:         modification, are permitted provided that the following conditions
0010:         are met:
0011:
0012:         1. Redistributions of source code must retain the above copyright
0013:            notice, this list of conditions, and the following disclaimer.
0014:
0015:         2. Redistributions in binary form must reproduce the above copyright
0016:            notice, this list of conditions, and the disclaimer that follows
0017:            these conditions in the documentation and/or other materials
0018:            provided with the distribution.
0019:
0020:         3. The name "JDOM" must not be used to endorse or promote products
0021:            derived from this software without prior written permission.  For
0022:            written permission, please contact <request_AT_jdom_DOT_org>.
0023:
0024:         4. Products derived from this software may not be called "JDOM", nor
0025:            may "JDOM" appear in their name, without prior written permission
0026:            from the JDOM Project Management <request_AT_jdom_DOT_org).
0027:
0028:         In addition, we request (but do not require) that you include in the
0029:         end-user documentation provided with the redistribution and/or in the
0030:         software itself an acknowledgement equivalent to the following:
0031:             "This product includes software developed by the
0032:              JDOM Project (http://www.jdom.org/)."
0033:         Alternatively, the acknowledgment may be graphical using the logos
0034:         available at http://www.jdom.org/images/logos.
0035:
0036:         THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0037:         WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0038:         OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0039:         DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
0040:         CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0041:         SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0042:         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0043:         USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0044:         ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0045:         OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0046:         OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0047:         SUCH DAMAGE.
0048:
0049:         This software consists of voluntary contributions made by many
0050:         individuals on behalf of the JDOM Project and was originally
0051:         created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
0052:         Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
0053:         on the JDOM Project, please see <http://www.jdom.org/>.
0054:
0055:         */
0056:
0057:        package org.jdom;
0058:
0059:        import java.util.*;
0060:
0061:        import org.jdom.filter.*;
0062:
0063:        /**
0064:         * A non-public list implementation holding only legal JDOM content, including
0065:         * content for Document or Element nodes. Users see this class as a simple List
0066:         * implementation.
0067:         *
0068:         * @see     CDATA
0069:         * @see     Comment
0070:         * @see     Element
0071:         * @see     EntityRef
0072:         * @see     ProcessingInstruction
0073:         * @see     Text
0074:         *
0075:         * @version $Revision: 1.39 $, $Date: 2004/02/28 03:30:27 $
0076:         * @author  Alex Rosen
0077:         * @author  Philippe Riand
0078:         * @author  Bradley S. Huffman
0079:         */
0080:        final class ContentList extends AbstractList implements 
0081:                java.io.Serializable {
0082:
0083:            private static final String CVS_ID = "@(#) $RCSfile: ContentList.java,v $ $Revision: 1.39 $ $Date: 2004/02/28 03:30:27 $ $Name: jdom_1_0 $";
0084:
0085:            private static final int INITIAL_ARRAY_SIZE = 5;
0086:
0087:            /**
0088:             * Used inner class FilterListIterator to help hasNext and
0089:             * hasPrevious the next index of our cursor (must be here
0090:             * for JDK1.1).
0091:             */
0092:            private static final int CREATE = 0;
0093:            private static final int HASPREV = 1;
0094:            private static final int HASNEXT = 2;
0095:            private static final int PREV = 3;
0096:            private static final int NEXT = 4;
0097:            private static final int ADD = 5;
0098:            private static final int REMOVE = 6;
0099:
0100:            /** Our backing list */
0101:            //    protected ArrayList list;
0102:            private Content elementData[];
0103:            private int size;
0104:
0105:            /** Document or Element this list belongs to */
0106:            private Parent parent;
0107:
0108:            /** Force either a Document or Element parent */
0109:            ContentList(Parent parent) {
0110:                this .parent = parent;
0111:            }
0112:
0113:            /**
0114:             * Package internal method to support building from sources that are
0115:             * 100% trusted.
0116:             *
0117:             * @param c content to add without any checks
0118:             */
0119:            final void uncheckedAddContent(Content c) {
0120:                c.parent = parent;
0121:                ensureCapacity(size + 1);
0122:                elementData[size++] = c;
0123:                modCount++;
0124:            }
0125:
0126:            /**
0127:             * Inserts the specified object at the specified position in this list.
0128:             * Shifts the object currently at that position (if any) and any
0129:             * subsequent objects to the right (adds one to their indices).
0130:             *
0131:             * @param index The location to set the value to.
0132:             * @param obj The object to insert into the list.
0133:             * throws IndexOutOfBoundsException if index < 0 || index > size()
0134:             */
0135:            public void add(int index, Object obj) {
0136:                if (obj == null) {
0137:                    throw new IllegalAddException("Cannot add null object");
0138:                }
0139:                if ((obj instanceof  Content)) {
0140:                    add(index, (Content) obj);
0141:                } else {
0142:                    throw new IllegalAddException("Class "
0143:                            + obj.getClass().getName()
0144:                            + " is of unrecognized type and cannot be added");
0145:                }
0146:            }
0147:
0148:            /**
0149:             * @see org.jdom.ContentList#add(int, org.jdom.Content)
0150:             */
0151:            private void documentCanContain(int index, Content child)
0152:                    throws IllegalAddException {
0153:                if (child instanceof  Element) {
0154:                    if (indexOfFirstElement() >= 0) {
0155:                        throw new IllegalAddException(
0156:                                "Cannot add a second root element, only one is allowed");
0157:                    }
0158:                    if (indexOfDocType() > index) {
0159:                        throw new IllegalAddException(
0160:                                "A root element cannot be added before the DocType");
0161:                    }
0162:                }
0163:                if (child instanceof  DocType) {
0164:                    if (indexOfDocType() >= 0) {
0165:                        throw new IllegalAddException(
0166:                                "Cannot add a second doctype, only one is allowed");
0167:                    }
0168:                    int firstElt = indexOfFirstElement();
0169:                    if (firstElt != -1 && firstElt < index) {
0170:                        throw new IllegalAddException(
0171:                                "A DocType cannot be added after the root element");
0172:                    }
0173:                }
0174:                if (child instanceof  CDATA) {
0175:                    throw new IllegalAddException(
0176:                            "A CDATA is not allowed at the document root");
0177:                }
0178:
0179:                if (child instanceof  Text) {
0180:                    throw new IllegalAddException(
0181:                            "A Text is not allowed at the document root");
0182:                }
0183:
0184:                if (child instanceof  EntityRef) {
0185:                    throw new IllegalAddException(
0186:                            "An EntityRef is not allowed at the document root");
0187:                }
0188:            }
0189:
0190:            private static void elementCanContain(int index, Content child)
0191:                    throws IllegalAddException {
0192:                if (child instanceof  DocType) {
0193:                    throw new IllegalAddException(
0194:                            "A DocType is not allowed except at the document level");
0195:                }
0196:            }
0197:
0198:            /**
0199:             * Check and add the <code>Element</code> to this list at
0200:             * the given index.
0201:             *
0202:             * @param index index where to add <code>Element</code>
0203:             * @param child <code>Element</code> to add
0204:             */
0205:            void add(int index, Content child) {
0206:                if (child == null) {
0207:                    throw new IllegalAddException("Cannot add null object");
0208:                }
0209:                if (parent instanceof  Document) {
0210:                    documentCanContain(index, child);
0211:                } else {
0212:                    elementCanContain(index, child);
0213:                }
0214:
0215:                if (child.getParent() != null) {
0216:                    Parent p = child.getParent();
0217:                    if (p instanceof  Document) {
0218:                        throw new IllegalAddException((Element) child,
0219:                                "The Content already has an existing parent document");
0220:                    } else {
0221:                        throw new IllegalAddException(
0222:                                "The Content already has an existing parent \""
0223:                                        + ((Element) p).getQualifiedName()
0224:                                        + "\"");
0225:                    }
0226:                }
0227:
0228:                if (child == parent) {
0229:                    throw new IllegalAddException(
0230:                            "The Element cannot be added to itself");
0231:                }
0232:
0233:                // Detect if we have <a><b><c/></b></a> and c.add(a)
0234:                if ((parent instanceof  Element && child instanceof  Element)
0235:                        && ((Element) child).isAncestor((Element) parent)) {
0236:                    throw new IllegalAddException(
0237:                            "The Element cannot be added as a descendent of itself");
0238:                }
0239:
0240:                if (index < 0 || index > size) {
0241:                    throw new IndexOutOfBoundsException("Index: " + index
0242:                            + " Size: " + size());
0243:                }
0244:
0245:                child.setParent(parent);
0246:
0247:                ensureCapacity(size + 1);
0248:                if (index == size) {
0249:                    elementData[size++] = child;
0250:                } else {
0251:                    System.arraycopy(elementData, index, elementData,
0252:                            index + 1, size - index);
0253:                    elementData[index] = child;
0254:                    size++;
0255:                }
0256:                modCount++;
0257:            }
0258:
0259:            /**
0260:             * Add the specified collecton to the end of this list.
0261:             *
0262:             * @param collection The collection to add to the list.
0263:             * @return <code>true</code> if the list was modified as a result of
0264:             *                           the add.
0265:             */
0266:            public boolean addAll(Collection collection) {
0267:                return addAll(size(), collection);
0268:            }
0269:
0270:            /**
0271:             * Inserts the specified collecton at the specified position in this list.
0272:             * Shifts the object currently at that position (if any) and any
0273:             * subsequent objects to the right (adds one to their indices).
0274:             *
0275:             * @param index The offset to start adding the data in the collection
0276:             * @param collection The collection to insert into the list.
0277:             * @return <code>true</code> if the list was modified as a result of
0278:             *                           the add.
0279:             * throws IndexOutOfBoundsException if index < 0 || index > size()
0280:             */
0281:            public boolean addAll(int index, Collection collection) {
0282:                if (index < 0 || index > size) {
0283:                    throw new IndexOutOfBoundsException("Index: " + index
0284:                            + " Size: " + size());
0285:                }
0286:
0287:                if ((collection == null) || (collection.size() == 0)) {
0288:                    return false;
0289:                }
0290:                ensureCapacity(size() + collection.size());
0291:
0292:                int count = 0;
0293:                try {
0294:                    Iterator i = collection.iterator();
0295:                    while (i.hasNext()) {
0296:                        Object obj = i.next();
0297:                        add(index + count, obj);
0298:                        count++;
0299:                    }
0300:                } catch (RuntimeException exception) {
0301:                    for (int i = 0; i < count; i++) {
0302:                        remove(index);
0303:                    }
0304:                    throw exception;
0305:                }
0306:
0307:                return true;
0308:            }
0309:
0310:            /**
0311:             * Clear the current list.
0312:             */
0313:            public void clear() {
0314:                if (elementData != null) {
0315:                    for (int i = 0; i < size; i++) {
0316:                        Content obj = elementData[i];
0317:                        removeParent(obj);
0318:                    }
0319:                    elementData = null;
0320:                    size = 0;
0321:                }
0322:                modCount++;
0323:            }
0324:
0325:            /**
0326:             * Clear the current list and set it to the contents
0327:             * of the <code>Collection</code>.
0328:             * object.
0329:             *
0330:             * @param collection The collection to use.
0331:             */
0332:            void clearAndSet(Collection collection) {
0333:                Content[] old = elementData;
0334:                int oldSize = size;
0335:
0336:                elementData = null;
0337:                size = 0;
0338:
0339:                if ((collection != null) && (collection.size() != 0)) {
0340:                    ensureCapacity(collection.size());
0341:                    try {
0342:                        addAll(0, collection);
0343:                    } catch (RuntimeException exception) {
0344:                        elementData = old;
0345:                        size = oldSize;
0346:                        throw exception;
0347:                    }
0348:                }
0349:
0350:                if (old != null) {
0351:                    for (int i = 0; i < oldSize; i++) {
0352:                        removeParent(old[i]);
0353:                    }
0354:                }
0355:                modCount++;
0356:            }
0357:
0358:            /**
0359:             * Increases the capacity of this <code>ContentList</code> instance,
0360:             * if necessary, to ensure that it can hold at least the number of
0361:             * items specified by the minimum capacity argument.
0362:             *
0363:             * @param minCapacity the desired minimum capacity.
0364:             */
0365:            void ensureCapacity(int minCapacity) {
0366:                if (elementData == null) {
0367:                    elementData = new Content[Math.max(minCapacity,
0368:                            INITIAL_ARRAY_SIZE)];
0369:                } else {
0370:                    int oldCapacity = elementData.length;
0371:                    if (minCapacity > oldCapacity) {
0372:                        Object oldData[] = elementData;
0373:                        int newCapacity = (oldCapacity * 3) / 2 + 1;
0374:                        if (newCapacity < minCapacity)
0375:                            newCapacity = minCapacity;
0376:                        elementData = new Content[newCapacity];
0377:                        System.arraycopy(oldData, 0, elementData, 0, size);
0378:                    }
0379:                }
0380:            }
0381:
0382:            /**
0383:             * Return the object at the specified offset.
0384:             *
0385:             * @param index The offset of the object.
0386:             * @return The Object which was returned.
0387:             */
0388:            public Object get(int index) {
0389:                if (index < 0 || index >= size) {
0390:                    throw new IndexOutOfBoundsException("Index: " + index
0391:                            + " Size: " + size());
0392:                }
0393:                return elementData[index];
0394:            }
0395:
0396:            /**
0397:             * Return a view of this list based on the given filter.
0398:             *
0399:             * @param filter <code>Filter</code> for this view.
0400:             * @return a list representing the rules of the <code>Filter</code>.
0401:             */
0402:            List getView(Filter filter) {
0403:                return new FilterList(filter);
0404:            }
0405:
0406:            /**
0407:             * Return the index of the first Element in the list.  If the parent
0408:             * is a <code>Document</code> then the element is the root element.
0409:             * If the list contains no Elements, it returns -1.
0410:             *
0411:             * @return index of first element, or -1 if one doesn't exist
0412:             */
0413:            int indexOfFirstElement() {
0414:                if (elementData != null) {
0415:                    for (int i = 0; i < size; i++) {
0416:                        if (elementData[i] instanceof  Element) {
0417:                            return i;
0418:                        }
0419:                    }
0420:                }
0421:                return -1;
0422:            }
0423:
0424:            /**
0425:             * Return the index of the DocType element in the list. If the list contains
0426:             * no DocType, it returns -1.
0427:             *
0428:             * @return                     index of the DocType, or -1 if it doesn't
0429:             *                             exist
0430:             */
0431:            int indexOfDocType() {
0432:                if (elementData != null) {
0433:                    for (int i = 0; i < size; i++) {
0434:                        if (elementData[i] instanceof  DocType) {
0435:                            return i;
0436:                        }
0437:                    }
0438:                }
0439:                return -1;
0440:            }
0441:
0442:            /**
0443:             * Remove the object at the specified offset.
0444:             *
0445:             * @param index The offset of the object.
0446:             * @return The Object which was removed.
0447:             */
0448:            public Object remove(int index) {
0449:                if (index < 0 || index >= size)
0450:                    throw new IndexOutOfBoundsException("Index: " + index
0451:                            + " Size: " + size());
0452:
0453:                Content old = elementData[index];
0454:                removeParent(old);
0455:                int numMoved = size - index - 1;
0456:                if (numMoved > 0)
0457:                    System.arraycopy(elementData, index + 1, elementData,
0458:                            index, numMoved);
0459:                elementData[--size] = null; // Let gc do its work
0460:                modCount++;
0461:                return old;
0462:            }
0463:
0464:            /** Remove the parent of a Object */
0465:            private static void removeParent(Content c) {
0466:                c.setParent(null);
0467:            }
0468:
0469:            /**
0470:             * Set the object at the specified location to the supplied
0471:             * object.
0472:             *
0473:             * @param index The location to set the value to.
0474:             * @param obj The location to set the value to.
0475:             * @return The object which was replaced.
0476:             * throws IndexOutOfBoundsException if index < 0 || index >= size()
0477:             */
0478:            public Object set(int index, Object obj) {
0479:                if (index < 0 || index >= size)
0480:                    throw new IndexOutOfBoundsException("Index: " + index
0481:                            + " Size: " + size());
0482:
0483:                if ((obj instanceof  Element) && (parent instanceof  Document)) {
0484:                    int root = indexOfFirstElement();
0485:                    if ((root >= 0) && (root != index)) {
0486:                        throw new IllegalAddException(
0487:                                "Cannot add a second root element, only one is allowed");
0488:                    }
0489:                }
0490:
0491:                if ((obj instanceof  DocType) && (parent instanceof  Document)) {
0492:                    int docTypeIndex = indexOfDocType();
0493:                    if ((docTypeIndex >= 0) && (docTypeIndex != index)) {
0494:                        throw new IllegalAddException(
0495:                                "Cannot add a second doctype, only one is allowed");
0496:                    }
0497:                }
0498:
0499:                Object old = remove(index);
0500:                try {
0501:                    add(index, obj);
0502:                } catch (RuntimeException exception) {
0503:                    add(index, old);
0504:                    throw exception;
0505:                }
0506:                return old;
0507:            }
0508:
0509:            /**
0510:             * Return the number of items in this list
0511:             *
0512:             * @return The number of items in this list.
0513:             */
0514:            public int size() {
0515:                return size;
0516:            }
0517:
0518:            /**
0519:             * Return this list as a <code>String</code>
0520:             *
0521:             * @return The number of items in this list.
0522:             */
0523:            public String toString() {
0524:                return super .toString();
0525:            }
0526:
0527:            /** Give access of ContentList.modCount to FilterList */
0528:            private int getModCount() {
0529:                return modCount;
0530:            }
0531:
0532:            /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */
0533:            /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */
0534:
0535:            /**
0536:             * <code>FilterList</code> represents legal JDOM content, including content
0537:             * for <code>Document</code>s or <code>Element</code>s.
0538:             */
0539:
0540:            class FilterList extends AbstractList implements 
0541:                    java.io.Serializable {
0542:
0543:                /** The Filter */
0544:                Filter filter;
0545:
0546:                /** Current number of items in this view */
0547:                int count = 0;
0548:
0549:                /** Expected modCount in our backing list */
0550:                int expected = -1;
0551:
0552:                // Implementation Note: Directly after size() is called, expected
0553:                //       is sync'd with ContentList.modCount and count provides
0554:                //       the true size of this view.  Before the first call to
0555:                //       size() or if the backing list is modified outside this
0556:                //       FilterList, both might contain bogus values and should
0557:                //       not be used without first calling size();
0558:
0559:                /**
0560:                 * Create a new instance of the FilterList with the specified Filter.
0561:                 */
0562:                FilterList(Filter filter) {
0563:                    this .filter = filter;
0564:                }
0565:
0566:                /**
0567:                 * Inserts the specified object at the specified position in this list.
0568:                 * Shifts the object currently at that position (if any) and any
0569:                 * subsequent objects to the right (adds one to their indices).
0570:                 *
0571:                 * @param index The location to set the value to.
0572:                 * @param obj The object to insert into the list.
0573:                 * throws IndexOutOfBoundsException if index < 0 || index > size()
0574:                 */
0575:                public void add(int index, Object obj) {
0576:                    if (filter.matches(obj)) {
0577:                        int adjusted = getAdjustedIndex(index);
0578:                        ContentList.this .add(adjusted, obj);
0579:                        expected++;
0580:                        count++;
0581:                    } else
0582:                        throw new IllegalAddException("Filter won't allow the "
0583:                                + obj.getClass().getName() + " '" + obj
0584:                                + "' to be added to the list");
0585:                }
0586:
0587:                /**
0588:                 * Return the object at the specified offset.
0589:                 *
0590:                 * @param index The offset of the object.
0591:                 * @return The Object which was returned.
0592:                 */
0593:                public Object get(int index) {
0594:                    int adjusted = getAdjustedIndex(index);
0595:                    return ContentList.this .get(adjusted);
0596:                }
0597:
0598:                public Iterator iterator() {
0599:                    return new FilterListIterator(filter, 0);
0600:                }
0601:
0602:                public ListIterator listIterator() {
0603:                    return new FilterListIterator(filter, 0);
0604:                }
0605:
0606:                public ListIterator listIterator(int index) {
0607:                    return new FilterListIterator(filter, index);
0608:                }
0609:
0610:                /**
0611:                 * Remove the object at the specified offset.
0612:                 *
0613:                 * @param index The offset of the object.
0614:                 * @return The Object which was removed.
0615:                 */
0616:                public Object remove(int index) {
0617:                    int adjusted = getAdjustedIndex(index);
0618:                    Object old = ContentList.this .get(adjusted);
0619:                    if (filter.matches(old)) {
0620:                        old = ContentList.this .remove(adjusted);
0621:                        expected++;
0622:                        count--;
0623:                    } else {
0624:                        throw new IllegalAddException("Filter won't allow the "
0625:                                + (old.getClass()).getName() + " '" + old
0626:                                + "' (index " + index + ") to be removed");
0627:                    }
0628:                    return old;
0629:                }
0630:
0631:                /**
0632:                 * Set the object at the specified location to the supplied
0633:                 * object.
0634:                 *
0635:                 * @param index The location to set the value to.
0636:                 * @param obj The location to set the value to.
0637:                 * @return The object which was replaced.
0638:                 * throws IndexOutOfBoundsException if index < 0 || index >= size()
0639:                 */
0640:                public Object set(int index, Object obj) {
0641:                    Object old = null;
0642:                    if (filter.matches(obj)) {
0643:                        int adjusted = getAdjustedIndex(index);
0644:                        old = ContentList.this .get(adjusted);
0645:                        if (!filter.matches(old)) {
0646:                            throw new IllegalAddException(
0647:                                    "Filter won't allow the "
0648:                                            + (old.getClass()).getName() + " '"
0649:                                            + old + "' (index " + index
0650:                                            + ") to be removed");
0651:                        }
0652:                        old = ContentList.this .set(adjusted, obj);
0653:                        expected += 2;
0654:                    } else {
0655:                        throw new IllegalAddException(
0656:                                "Filter won't allow index " + index
0657:                                        + " to be set to "
0658:                                        + (obj.getClass()).getName());
0659:                    }
0660:                    return old;
0661:                }
0662:
0663:                /**
0664:                 * Return the number of items in this list
0665:                 *
0666:                 * @return The number of items in this list.
0667:                 */
0668:                public int size() {
0669:                    // Implementation Note: Directly after size() is called, expected
0670:                    //       is sync'd with ContentList.modCount and count provides
0671:                    //       the true size of this view.  Before the first call to
0672:                    //       size() or if the backing list is modified outside this
0673:                    //       FilterList, both might contain bogus values and should
0674:                    //       not be used without first calling size();
0675:
0676:                    if (expected == ContentList.this .getModCount()) {
0677:                        return count;
0678:                    }
0679:
0680:                    count = 0;
0681:                    for (int i = 0; i < ContentList.this .size(); i++) {
0682:                        Object obj = ContentList.this .elementData[i];
0683:                        if (filter.matches(obj)) {
0684:                            count++;
0685:                        }
0686:                    }
0687:                    expected = ContentList.this .getModCount();
0688:                    return count;
0689:                }
0690:
0691:                /**
0692:                 * Return the adjusted index
0693:                 *
0694:                 * @param index Index of in this view.
0695:                 * @return True index in backing list
0696:                 */
0697:                final private int getAdjustedIndex(int index) {
0698:                    int adjusted = 0;
0699:                    for (int i = 0; i < ContentList.this .size; i++) {
0700:                        Object obj = ContentList.this .elementData[i];
0701:                        if (filter.matches(obj)) {
0702:                            if (index == adjusted) {
0703:                                return i;
0704:                            }
0705:                            adjusted++;
0706:                        }
0707:                    }
0708:
0709:                    if (index == adjusted) {
0710:                        return ContentList.this .size;
0711:                    }
0712:
0713:                    return ContentList.this .size + 1;
0714:                }
0715:            }
0716:
0717:            /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */
0718:            /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */
0719:
0720:            class FilterListIterator implements  ListIterator {
0721:
0722:                /** The Filter that applies */
0723:                Filter filter;
0724:
0725:                /** The last operation performed */
0726:                int lastOperation;
0727:
0728:                /** Initial start index in backing list */
0729:                int initialCursor;
0730:
0731:                /** Index in backing list of next object */
0732:                int cursor;
0733:
0734:                /** Index in backing list of last object returned */
0735:                int last;
0736:
0737:                /** Expected modCount in our backing list */
0738:                int expected;
0739:
0740:                /**
0741:                 * Default constructor
0742:                 */
0743:                FilterListIterator(Filter filter, int start) {
0744:                    this .filter = filter;
0745:                    initialCursor = initializeCursor(start);
0746:                    last = -1;
0747:                    expected = ContentList.this .getModCount();
0748:                    lastOperation = CREATE;
0749:                }
0750:
0751:                /**
0752:                 * Returns <code>true</code> if this list iterator has a next element.
0753:                 */
0754:                public boolean hasNext() {
0755:                    checkConcurrentModification();
0756:
0757:                    switch (lastOperation) {
0758:                    case CREATE:
0759:                        cursor = initialCursor;
0760:                        break;
0761:                    case PREV:
0762:                        cursor = last;
0763:                        break;
0764:                    case ADD:
0765:                    case NEXT:
0766:                        cursor = moveForward(last + 1);
0767:                        break;
0768:                    case REMOVE:
0769:                        cursor = moveForward(last);
0770:                        break;
0771:                    case HASPREV:
0772:                        cursor = moveForward(cursor + 1);
0773:                        break;
0774:                    case HASNEXT:
0775:                        break;
0776:                    default:
0777:                        throw new IllegalStateException("Unknown operation");
0778:                    }
0779:
0780:                    if (lastOperation != CREATE) {
0781:                        lastOperation = HASNEXT;
0782:                    }
0783:
0784:                    return (cursor < ContentList.this .size()) ? true : false;
0785:                }
0786:
0787:                /**
0788:                 * Returns the next element in the list.
0789:                 */
0790:                public Object next() {
0791:                    checkConcurrentModification();
0792:
0793:                    if (hasNext()) {
0794:                        last = cursor;
0795:                    } else {
0796:                        last = ContentList.this .size();
0797:                        throw new NoSuchElementException();
0798:                    }
0799:
0800:                    lastOperation = NEXT;
0801:                    return ContentList.this .get(last);
0802:                }
0803:
0804:                /**
0805:                 * Returns <code>true</code> if this list iterator has more
0806:                 * elements when traversing the list in the reverse direction.
0807:                 */
0808:                public boolean hasPrevious() {
0809:                    checkConcurrentModification();
0810:
0811:                    switch (lastOperation) {
0812:                    case CREATE:
0813:                        cursor = initialCursor;
0814:                        int size = ContentList.this .size();
0815:                        if (cursor >= size) {
0816:                            cursor = moveBackward(size - 1);
0817:                        }
0818:                        break;
0819:                    case PREV:
0820:                    case REMOVE:
0821:                        cursor = moveBackward(last - 1);
0822:                        break;
0823:                    case HASNEXT:
0824:                        cursor = moveBackward(cursor - 1);
0825:                        break;
0826:                    case ADD:
0827:                    case NEXT:
0828:                        cursor = last;
0829:                        break;
0830:                    case HASPREV:
0831:                        break;
0832:                    default:
0833:                        throw new IllegalStateException("Unknown operation");
0834:                    }
0835:
0836:                    if (lastOperation != CREATE) {
0837:                        lastOperation = HASPREV;
0838:                    }
0839:
0840:                    return (cursor < 0) ? false : true;
0841:                }
0842:
0843:                /**
0844:                 * Returns the previous element in the list.
0845:                 */
0846:                public Object previous() {
0847:                    checkConcurrentModification();
0848:
0849:                    if (hasPrevious()) {
0850:                        last = cursor;
0851:                    } else {
0852:                        last = -1;
0853:                        throw new NoSuchElementException();
0854:                    }
0855:
0856:                    lastOperation = PREV;
0857:                    return ContentList.this .get(last);
0858:                }
0859:
0860:                /**
0861:                 * Returns the index of the element that would be returned by a
0862:                 * subsequent call to <code>next</code>.
0863:                 */
0864:                public int nextIndex() {
0865:                    checkConcurrentModification();
0866:                    hasNext();
0867:
0868:                    int count = 0;
0869:                    for (int i = 0; i < ContentList.this .size(); i++) {
0870:                        if (filter.matches(ContentList.this .get(i))) {
0871:                            if (i == cursor) {
0872:                                return count;
0873:                            }
0874:                            count++;
0875:                        }
0876:                    }
0877:                    expected = ContentList.this .getModCount();
0878:                    return count;
0879:                }
0880:
0881:                /**
0882:                 * Returns the index of the element that would be returned by a
0883:                 * subsequent call to <code>previous</code>. (Returns -1 if the
0884:                 * list iterator is at the beginning of the list.)
0885:                 */
0886:                public int previousIndex() {
0887:                    checkConcurrentModification();
0888:
0889:                    if (hasPrevious()) {
0890:                        int count = 0;
0891:                        for (int i = 0; i < ContentList.this .size(); i++) {
0892:                            if (filter.matches(ContentList.this .get(i))) {
0893:                                if (i == cursor) {
0894:                                    return count;
0895:                                }
0896:                                count++;
0897:                            }
0898:                        }
0899:                    }
0900:                    return -1;
0901:                }
0902:
0903:                /**
0904:                 * Inserts the specified element into the list.
0905:                 */
0906:                public void add(Object obj) {
0907:                    checkConcurrentModification();
0908:
0909:                    if (filter.matches(obj)) {
0910:                        last = cursor + 1;
0911:                        ContentList.this .add(last, obj);
0912:                    } else {
0913:                        throw new IllegalAddException(
0914:                                "Filter won't allow add of "
0915:                                        + (obj.getClass()).getName());
0916:                    }
0917:                    expected = ContentList.this .getModCount();
0918:                    lastOperation = ADD;
0919:                }
0920:
0921:                /**
0922:                 * Removes from the list the last element that was returned by
0923:                 * <code>next</code> or <code>previous</code>.
0924:                 * the last call to <code>next</code> or <code>previous</code>.
0925:                 */
0926:                public void remove() {
0927:                    checkConcurrentModification();
0928:
0929:                    if ((last < 0) || (lastOperation == REMOVE)) {
0930:                        throw new IllegalStateException(
0931:                                "no preceeding call to " + "prev() or next()");
0932:                    }
0933:
0934:                    if (lastOperation == ADD) {
0935:                        throw new IllegalStateException("cannot call remove() "
0936:                                + "after add()");
0937:                    }
0938:
0939:                    Object old = ContentList.this .get(last);
0940:                    if (filter.matches(old)) {
0941:                        ContentList.this .remove(last);
0942:                    } else
0943:                        throw new IllegalAddException("Filter won't allow "
0944:                                + (old.getClass()).getName() + " (index "
0945:                                + last + ") to be removed");
0946:                    expected = ContentList.this .getModCount();
0947:                    lastOperation = REMOVE;
0948:                }
0949:
0950:                /**
0951:                 * Replaces the last element returned by <code>next</code> or
0952:                 * <code>previous</code> with the specified element.
0953:                 */
0954:                public void set(Object obj) {
0955:                    checkConcurrentModification();
0956:
0957:                    if ((lastOperation == ADD) || (lastOperation == REMOVE)) {
0958:                        throw new IllegalStateException(
0959:                                "cannot call set() after "
0960:                                        + "add() or remove()");
0961:                    }
0962:
0963:                    if (last < 0) {
0964:                        throw new IllegalStateException(
0965:                                "no preceeding call to " + "prev() or next()");
0966:                    }
0967:
0968:                    if (filter.matches(obj)) {
0969:                        Object old = ContentList.this .get(last);
0970:                        if (!filter.matches(old)) {
0971:                            throw new IllegalAddException("Filter won't allow "
0972:                                    + (old.getClass()).getName() + " (index "
0973:                                    + last + ") to be removed");
0974:                        }
0975:                        ContentList.this .set(last, obj);
0976:                    } else {
0977:                        throw new IllegalAddException(
0978:                                "Filter won't allow index " + last
0979:                                        + " to be set to "
0980:                                        + (obj.getClass()).getName());
0981:                    }
0982:
0983:                    expected = ContentList.this .getModCount();
0984:                    // Don't set lastOperation
0985:                }
0986:
0987:                /**
0988:                 * Returns index in the backing list by moving forward start
0989:                 * objects that match our filter.
0990:                 */
0991:                private int initializeCursor(int start) {
0992:                    if (start < 0) {
0993:                        throw new IndexOutOfBoundsException("Index: " + start);
0994:                    }
0995:
0996:                    int count = 0;
0997:                    for (int i = 0; i < ContentList.this .size(); i++) {
0998:                        Object obj = ContentList.this .get(i);
0999:                        if (filter.matches(obj)) {
1000:                            if (start == count) {
1001:                                return i;
1002:                            }
1003:                            count++;
1004:                        }
1005:                    }
1006:
1007:                    if (start > count) {
1008:                        throw new IndexOutOfBoundsException("Index: " + start
1009:                                + " Size: " + count);
1010:                    }
1011:
1012:                    return ContentList.this .size();
1013:                }
1014:
1015:                /**
1016:                 * Returns index in the backing list of the next object matching
1017:                 * our filter, starting at the given index and moving forwards.
1018:                 */
1019:                private int moveForward(int start) {
1020:                    if (start < 0) {
1021:                        start = 0;
1022:                    }
1023:                    for (int i = start; i < ContentList.this .size(); i++) {
1024:                        Object obj = ContentList.this .get(i);
1025:                        if (filter.matches(obj)) {
1026:                            return i;
1027:                        }
1028:                    }
1029:                    return ContentList.this .size();
1030:                }
1031:
1032:                /**
1033:                 * Returns index in the backing list of the next object matching
1034:                 * our filter, starting at the given index and moving backwards.
1035:                 */
1036:                private int moveBackward(int start) {
1037:                    if (start >= ContentList.this .size()) {
1038:                        start = ContentList.this .size() - 1;
1039:                    }
1040:
1041:                    for (int i = start; i >= 0; --i) {
1042:                        Object obj = ContentList.this .get(i);
1043:                        if (filter.matches(obj)) {
1044:                            return i;
1045:                        }
1046:                    }
1047:                    return -1;
1048:                }
1049:
1050:                /**
1051:                 * Check if are backing list is being modified by someone else.
1052:                 */
1053:                private void checkConcurrentModification() {
1054:                    if (expected != ContentList.this .getModCount()) {
1055:                        throw new ConcurrentModificationException();
1056:                    }
1057:                }
1058:            }
1059:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.