Source Code Cross Referenced for FObj.java in  » Graphic-Library » fop » org » apache » fop » fo » 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 » Graphic Library » fop » org.apache.fop.fo 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        /* $Id: FObj.java 554104 2007-07-07 01:07:10Z adelmelle $ */
019:
020:        package org.apache.fop.fo;
021:
022:        import java.util.Collections;
023:        import java.util.Iterator;
024:        import java.util.List;
025:        import java.util.ListIterator;
026:        import java.util.Map;
027:        import java.util.NoSuchElementException;
028:        import java.util.Set;
029:
030:        import org.apache.fop.apps.FOPException;
031:        import org.apache.fop.fo.extensions.ExtensionAttachment;
032:        import org.apache.fop.fo.flow.Marker;
033:        import org.apache.fop.fo.properties.PropertyMaker;
034:        import org.apache.fop.util.QName;
035:        import org.xml.sax.Attributes;
036:        import org.xml.sax.Locator;
037:
038:        /**
039:         * Base class for representation of formatting objects and their processing.
040:         */
041:        public abstract class FObj extends FONode implements  Constants {
042:
043:            /** the list of property makers */
044:            private static PropertyMaker[] propertyListTable = FOPropertyMapping
045:                    .getGenericMappings();
046:
047:            /** 
048:             * pointer to the descendant subtree
049:             */
050:            protected FONode firstChild;
051:
052:            /** The list of extension attachments, null if none */
053:            private List extensionAttachments = null;
054:
055:            /** The map of foreign attributes, null if none */
056:            private Map foreignAttributes = null;
057:
058:            /** Used to indicate if this FO is either an Out Of Line FO (see rec)
059:             *  or a descendant of one. Used during FO validation.
060:             */
061:            private boolean isOutOfLineFODescendant = false;
062:
063:            /** Markers added to this element. */
064:            private Map markers = null;
065:
066:            // The value of properties relevant for all fo objects
067:            private String id = null;
068:
069:            // End of property values
070:
071:            /**
072:             * Create a new formatting object.
073:             * All formatting object classes extend this class.
074:             *
075:             * @param parent the parent node
076:             */
077:            public FObj(FONode parent) {
078:                super (parent);
079:
080:                // determine if isOutOfLineFODescendant should be set
081:                if (parent != null && parent instanceof  FObj) {
082:                    if (((FObj) parent).getIsOutOfLineFODescendant()) {
083:                        isOutOfLineFODescendant = true;
084:                    } else {
085:                        int foID = getNameId();
086:                        if (foID == FO_FLOAT || foID == FO_FOOTNOTE
087:                                || foID == FO_FOOTNOTE_BODY) {
088:                            isOutOfLineFODescendant = true;
089:                        }
090:                    }
091:                }
092:            }
093:
094:            /**
095:             * @see org.apache.fop.fo.FONode#clone(FONode, boolean)
096:             */
097:            public FONode clone(FONode parent, boolean removeChildren)
098:                    throws FOPException {
099:                FObj fobj = (FObj) super .clone(parent, removeChildren);
100:                if (removeChildren) {
101:                    fobj.firstChild = null;
102:                }
103:                return fobj;
104:            }
105:
106:            /**
107:             * Returns the PropertyMaker for a given property ID.
108:             * @param propId the property ID
109:             * @return the requested Property Maker
110:             */
111:            public static PropertyMaker getPropertyMakerFor(int propId) {
112:                return propertyListTable[propId];
113:            }
114:
115:            /**
116:             * @see org.apache.fop.fo.FONode#processNode
117:             */
118:            public void processNode(String elementName, Locator locator,
119:                    Attributes attlist, PropertyList pList) throws FOPException {
120:                setLocator(locator);
121:                pList.addAttributesToList(attlist);
122:                if (!inMarker() || "marker".equals(elementName)) {
123:                    pList.setWritingMode();
124:                    bind(pList);
125:                }
126:            }
127:
128:            /**
129:             * Create a default property list for this element. 
130:             * @see org.apache.fop.fo.FONode
131:             */
132:            protected PropertyList createPropertyList(PropertyList parent,
133:                    FOEventHandler foEventHandler) throws FOPException {
134:                return foEventHandler.getPropertyListMaker().make(this , parent);
135:            }
136:
137:            /**
138:             * Bind property values from the property list to the FO node.
139:             * Must be overridden in all FObj subclasses that have properties
140:             * applying to it.
141:             * @param pList the PropertyList where the properties can be found.
142:             * @throws FOPException if there is a problem binding the values
143:             */
144:            public void bind(PropertyList pList) throws FOPException {
145:                id = pList.get(PR_ID).getString();
146:            }
147:
148:            /**
149:             * @see org.apache.fop.fo.FONode#startOfNode
150:             * @throws FOPException FOP Exception
151:             */
152:            protected void startOfNode() throws FOPException {
153:                if (id != null) {
154:                    checkId(id);
155:                }
156:            }
157:
158:            /**
159:             * Setup the id for this formatting object.
160:             * Most formatting objects can have an id that can be referenced.
161:             * This methods checks that the id isn't already used by another FO
162:             * 
163:             * @param id    the id to check
164:             * @throws ValidationException if the ID is already defined elsewhere
165:             *                              (strict validation only)
166:             */
167:            private void checkId(String id) throws ValidationException {
168:                if (!inMarker() && !id.equals("")) {
169:                    Set idrefs = getFOEventHandler().getIDReferences();
170:                    if (!idrefs.contains(id)) {
171:                        idrefs.add(id);
172:                    } else {
173:                        if (getUserAgent().validateStrictly()) {
174:                            throw new ValidationException(
175:                                    "Property id \""
176:                                            + id
177:                                            + "\" previously used; id values must be unique"
178:                                            + " in document.", locator);
179:                        } else {
180:                            if (log.isWarnEnabled()) {
181:                                StringBuffer msg = new StringBuffer();
182:                                msg.append("Found non-unique id on ").append(
183:                                        getName());
184:                                if (locator.getLineNumber() != -1) {
185:                                    msg.append(" (at ").append(
186:                                            locator.getLineNumber())
187:                                            .append("/").append(
188:                                                    locator.getColumnNumber())
189:                                            .append(")");
190:                                }
191:                                msg
192:                                        .append("\nAny reference to it will be considered "
193:                                                + "a reference to the first occurrence "
194:                                                + "in the document.");
195:                                log.warn(msg);
196:                            }
197:                        }
198:                    }
199:                }
200:            }
201:
202:            /**
203:             * Returns Out Of Line FO Descendant indicator.
204:             * @return true if Out of Line FO or Out Of Line descendant, false otherwise
205:             */
206:            public boolean getIsOutOfLineFODescendant() {
207:                return isOutOfLineFODescendant;
208:            }
209:
210:            /**
211:             * @see org.apache.fop.fo.FONode#addChildNode(FONode)
212:             */
213:            protected void addChildNode(FONode child) throws FOPException {
214:                if (canHaveMarkers() && child.getNameId() == FO_MARKER) {
215:                    addMarker((Marker) child);
216:                } else {
217:                    ExtensionAttachment attachment = child
218:                            .getExtensionAttachment();
219:                    if (attachment != null) {
220:                        /* This removes the element from the normal children, 
221:                         * so no layout manager is being created for them 
222:                         * as they are only additional information.
223:                         */
224:                        addExtensionAttachment(attachment);
225:                    } else {
226:                        if (firstChild == null) {
227:                            firstChild = child;
228:                        } else {
229:                            FONode prevChild = firstChild;
230:                            while (prevChild.siblings != null
231:                                    && prevChild.siblings[1] != null) {
232:                                prevChild = prevChild.siblings[1];
233:                            }
234:                            FONode.attachSiblings(prevChild, child);
235:                        }
236:                    }
237:                }
238:            }
239:
240:            /**
241:             * Used by RetrieveMarker during Marker-subtree cloning
242:             * @param child     the (cloned) child node
243:             * @param parent    the (cloned) parent node
244:             * @throws FOPException when the child could not be added to the parent
245:             */
246:            protected static void addChildTo(FONode child, FObj parent)
247:                    throws FOPException {
248:                parent.addChildNode(child);
249:            }
250:
251:            /** @see org.apache.fop.fo.FONode#removeChild(org.apache.fop.fo.FONode) */
252:            public void removeChild(FONode child) {
253:                FONode nextChild = null;
254:                if (child.siblings != null) {
255:                    nextChild = child.siblings[1];
256:                }
257:                if (child == firstChild) {
258:                    firstChild = nextChild;
259:                    if (firstChild != null) {
260:                        firstChild.siblings[0] = null;
261:                    }
262:                } else {
263:                    FONode prevChild = child.siblings[0];
264:                    prevChild.siblings[1] = nextChild;
265:                    if (nextChild != null) {
266:                        nextChild.siblings[0] = prevChild;
267:                    }
268:                }
269:            }
270:
271:            /**
272:             * Find the nearest parent, grandparent, etc. FONode that is also an FObj
273:             * @return FObj the nearest ancestor FONode that is an FObj
274:             */
275:            public FObj findNearestAncestorFObj() {
276:                FONode par = parent;
277:                while (par != null && !(par instanceof  FObj)) {
278:                    par = par.parent;
279:                }
280:                return (FObj) par;
281:            }
282:
283:            /**
284:             * Check if this formatting object generates reference areas.
285:             * @return true if generates reference areas
286:             * @todo see if needed
287:             */
288:            public boolean generatesReferenceAreas() {
289:                return false;
290:            }
291:
292:            /**
293:             * @see org.apache.fop.fo.FONode#getChildNodes()
294:             */
295:            public FONodeIterator getChildNodes() {
296:                if (firstChild != null) {
297:                    return new FObjIterator(this );
298:                }
299:                return null;
300:            }
301:
302:            /**
303:             * Return an iterator over the object's childNodes starting
304:             * at the passed-in node (= first call to iterator.next() will
305:             * return childNode)
306:             * @param childNode First node in the iterator
307:             * @return A ListIterator or null if childNode isn't a child of
308:             * this FObj.
309:             */
310:            public FONodeIterator getChildNodes(FONode childNode) {
311:                FONodeIterator it = getChildNodes();
312:                if (it != null) {
313:                    if (firstChild == childNode) {
314:                        return it;
315:                    } else {
316:                        while (it.hasNext()
317:                                && it.nextNode().siblings[1] != childNode) {
318:                            //nop
319:                        }
320:                        if (it.hasNext()) {
321:                            return it;
322:                        } else {
323:                            return null;
324:                        }
325:                    }
326:                }
327:                return null;
328:            }
329:
330:            /**
331:             * Notifies a FObj that one of it's children is removed.
332:             * This method is subclassed by Block to clear the 
333:             * firstInlineChild variable in case it doesn't generate
334:             * any areas (see addMarker()).
335:             * @param node the node that was removed
336:             */
337:            protected void notifyChildRemoval(FONode node) {
338:                //nop
339:            }
340:
341:            /**
342:             * Add the marker to this formatting object.
343:             * If this object can contain markers it checks that the marker
344:             * has a unique class-name for this object and that it is
345:             * the first child.
346:             * @param marker Marker to add.
347:             */
348:            protected void addMarker(Marker marker) {
349:                String mcname = marker.getMarkerClassName();
350:                if (firstChild != null) {
351:                    // check for empty childNodes
352:                    for (Iterator iter = getChildNodes(); iter.hasNext();) {
353:                        FONode node = (FONode) iter.next();
354:                        if (node instanceof  FObj
355:                                || (node instanceof  FOText && ((FOText) node)
356:                                        .willCreateArea())) {
357:                            log.error("fo:marker must be an initial child: "
358:                                    + mcname);
359:                            return;
360:                        } else if (node instanceof  FOText) {
361:                            iter.remove();
362:                            notifyChildRemoval(node);
363:                        }
364:                    }
365:                }
366:                if (markers == null) {
367:                    markers = new java.util.HashMap();
368:                }
369:                if (!markers.containsKey(mcname)) {
370:                    markers.put(mcname, marker);
371:                } else {
372:                    log.error("fo:marker 'marker-class-name' "
373:                            + "must be unique for same parent: " + mcname);
374:                }
375:            }
376:
377:            /**
378:             * @return true if there are any Markers attached to this object
379:             */
380:            public boolean hasMarkers() {
381:                return markers != null && !markers.isEmpty();
382:            }
383:
384:            /**
385:             * @return the collection of Markers attached to this object
386:             */
387:            public Map getMarkers() {
388:                return markers;
389:            }
390:
391:            /** @see org.apache.fop.fo.FONode#gatherContextInfo() */
392:            protected String gatherContextInfo() {
393:                if (getLocator() != null) {
394:                    return super .gatherContextInfo();
395:                } else {
396:                    ListIterator iter = getChildNodes();
397:                    if (iter == null) {
398:                        return null;
399:                    }
400:                    StringBuffer sb = new StringBuffer();
401:                    while (iter.hasNext()) {
402:                        FONode node = (FONode) iter.next();
403:                        String s = node.gatherContextInfo();
404:                        if (s != null) {
405:                            if (sb.length() > 0) {
406:                                sb.append(", ");
407:                            }
408:                            sb.append(s);
409:                        }
410:                    }
411:                    return (sb.length() > 0 ? sb.toString() : null);
412:                }
413:            }
414:
415:            /**
416:             * Convenience method for validity checking.  Checks if the
417:             * incoming node is a member of the "%block;" parameter entity
418:             * as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations
419:             * @param nsURI namespace URI of incoming node
420:             * @param lName local name (i.e., no prefix) of incoming node 
421:             * @return true if a member, false if not
422:             */
423:            protected boolean isBlockItem(String nsURI, String lName) {
424:                return (FO_URI.equals(nsURI) && (lName.equals("block")
425:                        || lName.equals("table")
426:                        || lName.equals("table-and-caption")
427:                        || lName.equals("block-container")
428:                        || lName.equals("list-block") || lName.equals("float") || isNeutralItem(
429:                        nsURI, lName)));
430:            }
431:
432:            /**
433:             * Convenience method for validity checking.  Checks if the
434:             * incoming node is a member of the "%inline;" parameter entity
435:             * as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations
436:             * @param nsURI namespace URI of incoming node
437:             * @param lName local name (i.e., no prefix) of incoming node 
438:             * @return true if a member, false if not
439:             */
440:            protected boolean isInlineItem(String nsURI, String lName) {
441:                return (FO_URI.equals(nsURI) && (lName.equals("bidi-override")
442:                        || lName.equals("character")
443:                        || lName.equals("external-graphic")
444:                        || lName.equals("instream-foreign-object")
445:                        || lName.equals("inline")
446:                        || lName.equals("inline-container")
447:                        || lName.equals("leader")
448:                        || lName.equals("page-number")
449:                        || lName.equals("page-number-citation")
450:                        || lName.equals("page-number-citation-last")
451:                        || lName.equals("basic-link")
452:                        || (lName.equals("multi-toggle") && (getNameId() == FO_MULTI_CASE || findAncestor(FO_MULTI_CASE) > 0))
453:                        || (lName.equals("footnote") && !isOutOfLineFODescendant) || isNeutralItem(
454:                        nsURI, lName)));
455:            }
456:
457:            /**
458:             * Convenience method for validity checking.  Checks if the
459:             * incoming node is a member of the "%block;" parameter entity
460:             * or "%inline;" parameter entity
461:             * @param nsURI namespace URI of incoming node
462:             * @param lName local name (i.e., no prefix) of incoming node 
463:             * @return true if a member, false if not
464:             */
465:            protected boolean isBlockOrInlineItem(String nsURI, String lName) {
466:                return (isBlockItem(nsURI, lName) || isInlineItem(nsURI, lName));
467:            }
468:
469:            /**
470:             * Convenience method for validity checking.  Checks if the
471:             * incoming node is a member of the neutral item list
472:             * as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations
473:             * @param nsURI namespace URI of incoming node
474:             * @param lName local name (i.e., no prefix) of incoming node 
475:             * @return true if a member, false if not
476:             */
477:            protected boolean isNeutralItem(String nsURI, String lName) {
478:                return (FO_URI.equals(nsURI) && (lName.equals("multi-switch")
479:                        || lName.equals("multi-properties")
480:                        || lName.equals("wrapper")
481:                        || (!isOutOfLineFODescendant && lName.equals("float")) || lName
482:                        .equals("retrieve-marker")));
483:            }
484:
485:            /**
486:             * Convenience method for validity checking.  Checks if the
487:             * current node has an ancestor of a given name.
488:             * @param ancestorID    ID of node name to check for (e.g., FO_ROOT)
489:             * @return number of levels above FO where ancestor exists, 
490:             *         -1 if not found
491:             */
492:            protected int findAncestor(int ancestorID) {
493:                int found = 1;
494:                FONode temp = getParent();
495:                while (temp != null) {
496:                    if (temp.getNameId() == ancestorID) {
497:                        return found;
498:                    }
499:                    found += 1;
500:                    temp = temp.getParent();
501:                }
502:                return -1;
503:            }
504:
505:            /** @return the "id" property. */
506:            public String getId() {
507:                return id;
508:            }
509:
510:            /** @return whether this object has an id set */
511:            public boolean hasId() {
512:                return id != null && id.length() > 0;
513:            }
514:
515:            /** @see org.apache.fop.fo.FONode#getNamespaceURI() */
516:            public String getNamespaceURI() {
517:                return FOElementMapping.URI;
518:            }
519:
520:            /** @see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */
521:            public String getNormalNamespacePrefix() {
522:                return "fo";
523:            }
524:
525:            /**
526:             * Add a new extension attachment to this FObj. 
527:             * (see org.apache.fop.fo.FONode for details)
528:             * 
529:             * @param attachment the attachment to add.
530:             */
531:            public void addExtensionAttachment(ExtensionAttachment attachment) {
532:                if (attachment == null) {
533:                    throw new NullPointerException(
534:                            "Parameter attachment must not be null");
535:                }
536:                if (extensionAttachments == null) {
537:                    extensionAttachments = new java.util.ArrayList();
538:                }
539:                if (log.isDebugEnabled()) {
540:                    log.debug("ExtensionAttachment of category "
541:                            + attachment.getCategory() + " added to "
542:                            + getName() + ": " + attachment);
543:                }
544:                extensionAttachments.add(attachment);
545:            }
546:
547:            /** @return the extension attachments of this FObj. */
548:            public List getExtensionAttachments() {
549:                if (extensionAttachments == null) {
550:                    return Collections.EMPTY_LIST;
551:                } else {
552:                    return extensionAttachments;
553:                }
554:            }
555:
556:            /**
557:             * Adds a foreign attribute to this FObj.
558:             * @param attributeName the attribute name as a QName instance
559:             * @param value the attribute value
560:             */
561:            public void addForeignAttribute(QName attributeName, String value) {
562:                /* TODO: Handle this over FOP's property mechanism so we can use 
563:                 *       inheritance.
564:                 */
565:                if (attributeName == null) {
566:                    throw new NullPointerException(
567:                            "Parameter attributeName must not be null");
568:                }
569:                if (foreignAttributes == null) {
570:                    foreignAttributes = new java.util.HashMap();
571:                }
572:                foreignAttributes.put(attributeName, value);
573:            }
574:
575:            /** @return the map of foreign attributes */
576:            public Map getForeignAttributes() {
577:                if (foreignAttributes == null) {
578:                    return Collections.EMPTY_MAP;
579:                } else {
580:                    return foreignAttributes;
581:                }
582:            }
583:
584:            public class FObjIterator implements  FONodeIterator {
585:
586:                private static final int F_NONE_ALLOWED = 0;
587:                private static final int F_SET_ALLOWED = 1;
588:                private static final int F_REMOVE_ALLOWED = 2;
589:
590:                private FONode currentNode;
591:                private FObj parentNode;
592:                private int currentIndex;
593:                private int flags = F_NONE_ALLOWED;
594:
595:                protected FObjIterator(FObj parent) {
596:                    this .parentNode = parent;
597:                    this .currentNode = parent.firstChild;
598:                    this .currentIndex = 0;
599:                    this .flags = F_NONE_ALLOWED;
600:                }
601:
602:                /**
603:                 * @see FONodeIterator#parentNode()
604:                 */
605:                public FObj parentNode() {
606:                    return parentNode;
607:                }
608:
609:                /**
610:                 * @see java.util.ListIterator#next()
611:                 */
612:                public Object next() {
613:                    if (currentNode != null) {
614:                        if (currentIndex != 0) {
615:                            if (currentNode.siblings != null
616:                                    && currentNode.siblings[1] != null) {
617:                                currentNode = currentNode.siblings[1];
618:                            } else {
619:                                throw new NoSuchElementException();
620:                            }
621:                        }
622:                        currentIndex++;
623:                        flags |= (F_SET_ALLOWED | F_REMOVE_ALLOWED);
624:                        return currentNode;
625:                    } else {
626:                        throw new NoSuchElementException();
627:                    }
628:                }
629:
630:                /**
631:                 * @see java.util.ListIterator#previous()
632:                 */
633:                public Object previous() {
634:                    if (currentNode.siblings != null
635:                            && currentNode.siblings[0] != null) {
636:                        currentIndex--;
637:                        currentNode = currentNode.siblings[0];
638:                        flags |= (F_SET_ALLOWED | F_REMOVE_ALLOWED);
639:                        return currentNode;
640:                    } else {
641:                        throw new NoSuchElementException();
642:                    }
643:                }
644:
645:                /**
646:                 * @see java.util.ListIterator#set(Object)
647:                 */
648:                public void set(Object o) {
649:                    if ((flags & F_SET_ALLOWED) == F_SET_ALLOWED) {
650:                        FONode newNode = (FONode) o;
651:                        if (currentNode == parentNode.firstChild) {
652:                            parentNode.firstChild = newNode;
653:                        } else {
654:                            FONode.attachSiblings(currentNode.siblings[0],
655:                                    newNode);
656:                        }
657:                        if (currentNode.siblings != null
658:                                && currentNode.siblings[1] != null) {
659:                            FONode.attachSiblings(newNode,
660:                                    currentNode.siblings[1]);
661:                        }
662:                    } else {
663:                        throw new IllegalStateException();
664:                    }
665:                }
666:
667:                /**
668:                 * @see java.util.ListIterator#add(Object)
669:                 */
670:                public void add(Object o) {
671:                    FONode newNode = (FONode) o;
672:                    if (currentIndex == -1) {
673:                        if (currentNode != null) {
674:                            FONode.attachSiblings(newNode, currentNode);
675:                        }
676:                        parentNode.firstChild = newNode;
677:                        currentIndex = 0;
678:                        currentNode = newNode;
679:                    } else {
680:                        if (currentNode.siblings != null
681:                                && currentNode.siblings[1] != null) {
682:                            FONode.attachSiblings((FONode) o,
683:                                    currentNode.siblings[1]);
684:                        }
685:                        FONode.attachSiblings(currentNode, (FONode) o);
686:                    }
687:                    flags &= F_NONE_ALLOWED;
688:                }
689:
690:                /**
691:                 * @see java.util.ListIterator#hasNext()
692:                 */
693:                public boolean hasNext() {
694:                    return (currentNode != null)
695:                            && ((currentIndex == 0) || (currentNode.siblings != null && currentNode.siblings[1] != null));
696:                }
697:
698:                /**
699:                 * @see java.util.ListIterator#hasPrevious()
700:                 */
701:                public boolean hasPrevious() {
702:                    return (currentIndex != 0)
703:                            || (currentNode.siblings != null && currentNode.siblings[0] != null);
704:                }
705:
706:                /**
707:                 * @see java.util.ListIterator#nextIndex()
708:                 */
709:                public int nextIndex() {
710:                    return currentIndex + 1;
711:                }
712:
713:                /**
714:                 * @see java.util.ListIterator#previousIndex()
715:                 */
716:                public int previousIndex() {
717:                    return currentIndex - 1;
718:                }
719:
720:                /**
721:                 * @see java.util.ListIterator#remove()
722:                 */
723:                public void remove() {
724:                    if ((flags & F_REMOVE_ALLOWED) == F_REMOVE_ALLOWED) {
725:                        parentNode.removeChild(currentNode);
726:                        if (currentIndex == 0) {
727:                            //first node removed
728:                            currentNode = parentNode.firstChild;
729:                        } else if (currentNode.siblings != null
730:                                && currentNode.siblings[0] != null) {
731:                            currentNode = currentNode.siblings[0];
732:                            currentIndex--;
733:                        } else {
734:                            currentNode = null;
735:                        }
736:                        flags &= F_NONE_ALLOWED;
737:                    } else {
738:                        throw new IllegalStateException();
739:                    }
740:                }
741:
742:                public FONode lastNode() {
743:                    while (currentNode != null && currentNode.siblings != null
744:                            && currentNode.siblings[1] != null) {
745:                        currentNode = currentNode.siblings[1];
746:                        currentIndex++;
747:                    }
748:                    return currentNode;
749:                }
750:
751:                public FONode firstNode() {
752:                    currentNode = parentNode.firstChild;
753:                    currentIndex = 0;
754:                    return currentNode;
755:                }
756:
757:                public FONode nextNode() {
758:                    return (FONode) next();
759:                }
760:
761:                public FONode previousNode() {
762:                    return (FONode) previous();
763:                }
764:            }
765:
766:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.