Source Code Cross Referenced for PositionManager.java in  » Portal » uPortal_rel-2-6-1-GA » org » jasig » portal » layout » dlm » 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 » Portal » uPortal_rel 2 6 1 GA » org.jasig.portal.layout.dlm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright 2005 The JA-SIG Collaborative.  All rights reserved.
002:         *  See license distributed with this file and
003:         *  available online at http://www.uportal.org/license.html
004:         */
005:
006:        package org.jasig.portal.layout.dlm;
007:
008:        import java.util.ArrayList;
009:        import java.util.Arrays;
010:        import java.util.Comparator;
011:        import java.util.Iterator;
012:        import java.util.List;
013:
014:        import org.apache.commons.logging.Log;
015:        import org.apache.commons.logging.LogFactory;
016:        import org.jasig.portal.PortalException;
017:        import org.jasig.portal.layout.IUserLayoutStore;
018:        import org.jasig.portal.layout.UserLayoutStoreFactory;
019:        import org.jasig.portal.security.IPerson;
020:        import org.w3c.dom.Document;
021:        import org.w3c.dom.Element;
022:        import org.w3c.dom.Node;
023:
024:        /** 
025:         * Applies and updates position specifiers for child nodes in the
026:         * composite layout.
027:         * 
028:         * @version $Revision: 36294 $ $Date: 2005-11-10 12:36:31 -0700 (Thu, 10 Nov 2005) $
029:         * @since uPortal 2.5
030:         */
031:        public class PositionManager {
032:            public static final String RCS_ID = "@(#) $Header$";
033:            private static Log LOG = LogFactory.getLog(PositionManager.class);
034:
035:            private static RDBMDistributedLayoutStore dls = null;
036:
037:            /**
038:             * Hands back the single instance of RDBMDistributedLayoutStore. There is
039:             * already a method
040:             * for aquiring a single instance of the configured layout store so we
041:             * delegate over there so that all references refer to the same instance.
042:             * This method is solely for convenience so that we don't have to keep
043:             * calling UserLayoutStoreFactory and casting the resulting class.
044:             */
045:            private static RDBMDistributedLayoutStore getDLS() {
046:                if (dls == null) {
047:                    IUserLayoutStore uls = null;
048:                    uls = UserLayoutStoreFactory.getUserLayoutStoreImpl();
049:                    dls = (RDBMDistributedLayoutStore) uls;
050:                }
051:                return dls;
052:            }
053:
054:            /**
055:               This method and ones that it delegates to have the responsibility of
056:               organizing the child nodes of the passed in composite view parent node
057:               according to the order specified in the passed in position set and
058:               return via the passed in result set whether the personal layout
059:               fragment (one portion of which is the position set) or the incoporated
060:               layouts fragment (one portion of which is the compViewParent) were
061:               changed.
062:
063:               This may also include pulling nodes in from other parents under certain
064:               circumstances. For example, if allowed a user can move nodes that are
065:               not part of their personal layout fragment or PLF; the UI elements that
066:               they own. These node do not exist in their layout in the database but
067:               instead are merged in with their owned elements at log in and other
068:               times. So to move them during subsequent merges a position set can
069:               contain a position directive indicating the id of the node to be moved
070:               into a specific position in the sibling list and that well may refer to
071:               a node not in the sibling list to begin with. If the node no longer
072:               exists in the composite view then that position directive can safely be
073:               discarded.
074:
075:               Positioning is meant to preserve as much as possible the user's
076:               specified ordering of user interface elements but always respecting
077:               movement restrictions placed on those elements that are incorporated by
078:               their owners. So the following rules apply from most important to least.
079:
080:               1) nodes with moveAllowed="false" prevent nodes of lower precedence from
081:               being to their left or higher with left or higher defined as having a
082:               lower index in the sibling list. (applyLowerPrecRestriction)
083:
084:               2) nodes with moveAllowed="false" prevent nodes of equal precedence from
085:               moving from one side of this node to the other from their position as
086:               found in the compViewParent initially and prevents nodes with the same
087:               precedence from moving from other parents into this parent prior to the
088:               restricted node. Prior to implies a lower sibling index.
089:               (applyHoppingRestriction)
090:
091:               3) nodes with moveAllowed="false" prevent nodes of equal precedence
092:               lower in the sibling list from being reparented. (ie: moving to another
093:               parent) However, they can be deleted. (applyReparentingCheck)
094:
095:               4) nodes should be ordered as much as possible in the order specified by
096:               the user but in view of the above conditions. So if a user has moved
097:               nodes thus specifying some order and the owner of some node in that set
098:               then locks one of those nodes some of those nodes will have to move
099:               back to their orinial positions to conform with the rules above but for
100:               the remaining nodes they should be found in the same relative order
101:               specified by the user. (getOrder)
102:
103:               5) nodes not included in the order specified by the user (ie: nodes
104:               added since the user last ordered them) should maintain their relative
105:               order as much as possible and be appended to the end of the sibling
106:               list after all others rules have been applied. (getOrder)
107:
108:               Each of these rules is applied by a call to a method 5 being first and
109:               1 being last so that 1 has the highest precedence and last say. Once
110:               the final ordering is specified then it is applied to the children of
111:               the compViewParent and returned.
112:             */
113:            static void applyPositions(Element compViewParent,
114:                    Element positionSet, IntegrationResult result)
115:                    throws PortalException {
116:                if (positionSet == null || positionSet.getFirstChild() == null)
117:                    return;
118:
119:                ArrayList order = new ArrayList();
120:
121:                applyOrdering(order, compViewParent, positionSet);
122:                applyNoReparenting(order, compViewParent, positionSet);
123:                applyNoHopping(order, compViewParent, positionSet);
124:                applyLowerPrecedence(order, compViewParent, positionSet);
125:                evaluateAndApply(order, compViewParent, positionSet, result);
126:            }
127:
128:            /**
129:               This method determines if applying all of the positioning rules and
130:               restrictions ended up making changes to the compViewParent or the
131:               original position set. If changes are applicable to the CVP then they
132:               are applied. If the position set changed then the original stored in the
133:               PLF is updated.
134:             */
135:            static void evaluateAndApply(ArrayList order,
136:                    Element compViewParent, Element positionSet,
137:                    IntegrationResult result) throws PortalException {
138:                adjustPositionSet(order, positionSet, result);
139:
140:                if (hasAffectOnCVP(order, compViewParent)) {
141:                    applyToNodes(order, compViewParent);
142:                    result.changedILF = true;
143:                }
144:            }
145:
146:            /**
147:               This method trims down the position set to the position directives on
148:               the node info elements still having a position directive. Any directives
149:               that violated restrictions were removed from the node info objects so
150:               the position set should be made to match the order of those still
151:               having one.
152:             */
153:            static void adjustPositionSet(ArrayList order, Element positionSet,
154:                    IntegrationResult result) {
155:                Node nodeToMatch = positionSet.getFirstChild();
156:                Element nodeToInsertBefore = positionSet.getOwnerDocument()
157:                        .createElement("INSERT_POINT");
158:                positionSet.insertBefore(nodeToInsertBefore, nodeToMatch);
159:
160:                for (Iterator iter = order.iterator(); iter.hasNext();) {
161:                    NodeInfo ni = (NodeInfo) iter.next();
162:
163:                    if (ni.positionDirective != null) {
164:                        // found one check it against the current one in the position
165:                        // set to see if it is different. If so then indicate that
166:                        // something (the position set) has changed in the plf
167:                        if (ni.positionDirective != nodeToMatch)
168:                            result.changedPLF = true;
169:
170:                        // now bump the insertion point forward prior to
171:                        // moving on to the next position node to be evaluated
172:                        if (nodeToMatch != null)
173:                            nodeToMatch = nodeToMatch.getNextSibling();
174:
175:                        // now insert it prior to insertion point
176:                        positionSet.insertBefore(ni.positionDirective,
177:                                nodeToInsertBefore);
178:                    }
179:                }
180:
181:                // now for any left over after the insert point remove them.
182:
183:                while (nodeToInsertBefore.getNextSibling() != null)
184:                    positionSet
185:                            .removeChild(nodeToInsertBefore.getNextSibling());
186:
187:                // now remove the insertion point
188:                positionSet.removeChild(nodeToInsertBefore);
189:            }
190:
191:            /**
192:               This method compares the children by id in the order list with
193:               the order in the compViewParent's ui visible children and returns true
194:               if the ordering differs indicating that the positioning if needed.
195:             */
196:            static boolean hasAffectOnCVP(ArrayList order,
197:                    Element compViewParent) {
198:                if (order.size() == 0)
199:                    return false;
200:
201:                int idx = 0;
202:                Element child = (Element) compViewParent.getFirstChild();
203:                NodeInfo ni = (NodeInfo) order.get(idx);
204:
205:                if (child == null && ni != null) // most likely nodes to be pulled in
206:                    return true;
207:
208:                while (child != null) {
209:                    if (child.getAttribute("hidden").equals("false")
210:                            && (!child.getAttribute("chanID").equals("") || child
211:                                    .getAttribute("type").equals("regular"))) {
212:                        if (ni.id.equals(child.getAttribute(Constants.ATT_ID))) {
213:                            if (idx >= order.size() - 1) // at end of order list
214:                                return false;
215:
216:                            ni = (NodeInfo) order.get(++idx);
217:                        } else
218:                            // if not equal then return true
219:                            return true;
220:                    }
221:                    child = (Element) child.getNextSibling();
222:                }
223:                if (idx < order.size())
224:                    return true; // represents nodes to be pulled in
225:                return false;
226:            }
227:
228:            /**
229:               This method applies the ordering specified in the passed in order list
230:               to the child nodes of the compViewParent. Nodes specified in the list
231:               but located elsewhere are pulled in.
232:             */
233:            static void applyToNodes(ArrayList order, Element compViewParent) {
234:                // first set up a bogus node to assist with inserting
235:                Node insertPoint = compViewParent.getOwnerDocument()
236:                        .createElement("bogus");
237:                Node first = compViewParent.getFirstChild();
238:
239:                if (first != null)
240:                    compViewParent.insertBefore(insertPoint, first);
241:                else
242:                    compViewParent.appendChild(insertPoint);
243:
244:                // now pass through the order list inserting the nodes as you go
245:                for (int i = 0; i < order.size(); i++)
246:                    compViewParent.insertBefore(((NodeInfo) order.get(i)).node,
247:                            insertPoint);
248:
249:                compViewParent.removeChild(insertPoint);
250:            }
251:
252:            /**
253:               This method is responsible for preventing nodes with lower precedence
254:               from being located to the left (lower sibling order) of nodes having a
255:               higher precedence and moveAllowed="false".
256:             */
257:            static void applyLowerPrecedence(ArrayList order,
258:                    Element compViewParent, Element positionSet) {
259:                for (int i = 0; i < order.size(); i++) {
260:                    NodeInfo ni = (NodeInfo) order.get(i);
261:                    if (ni.node.getAttribute(Constants.ATT_MOVE_ALLOWED)
262:                            .equals("false")) {
263:                        for (int j = 0; j < i; j++) {
264:                            NodeInfo lefty = (NodeInfo) order.get(j);
265:                            if (lefty.precedence == null
266:                                    || lefty.precedence
267:                                            .isLessThan(ni.precedence)) {
268:                                order.remove(j);
269:                                order.add(i, lefty);
270:                            }
271:                        }
272:                    }
273:                }
274:            }
275:
276:            /**
277:               This method is responsible for preventing nodes with identical
278:               precedence in the same parent from hopping over each other so that a
279:               layout fragment can lock two tabs that are next to each other and they
280:               can only be separated by tabs with higher precedence.
281:
282:               If this situation is detected then the positioning of all nodes
283:               currently in the compViewParent is left as they are found in the CVP
284:               with any nodes brought in from
285:               other parents appended at the end with their relative order preserved.
286:             */
287:            static void applyNoHopping(ArrayList order, Element compViewParent,
288:                    Element positionSet) {
289:                if (isIllegalHoppingSpecified(order) == true) {
290:                    ArrayList cvpNodeInfos = new ArrayList();
291:
292:                    // pull those out of the position list from the CVP
293:                    for (int i = order.size() - 1; i >= 0; i--)
294:                        if (((NodeInfo) order.get(i)).indexInCVP != -1)
295:                            cvpNodeInfos.add(order.remove(i));
296:
297:                    // what is left is coming from other parents. Now push them back in
298:                    // in the order specified in the CVP
299:
300:                    Object[] nodeInfos = cvpNodeInfos.toArray();
301:                    Arrays.sort(nodeInfos, new NodeInfoComparator());
302:                    List list = Arrays.asList(nodeInfos);
303:                    order.addAll(0, list);
304:                }
305:            }
306:
307:            /**
308:               This method determines if any illegal hopping is being specified.
309:               To determine if the positioning is specifying an ordering that will
310:               result in hopping I need to determine for each node n in the list if
311:               any of the nodes to be positioned to its right currently lie to its
312:               left in the CVP and have moveAllowed="false" and have the same
313:               precedence or if any of the nodes to be positioned to its left currently
314:               lie to its right in the CVP and have moveAllowed="false" and have the
315:               same precedence.
316:
317:             */
318:            static boolean isIllegalHoppingSpecified(ArrayList order) {
319:                for (int i = 0; i < order.size(); i++) {
320:                    NodeInfo ni = (NodeInfo) order.get(i);
321:
322:                    // look for move restricted nodes
323:                    if (!ni.node.getAttribute(Constants.ATT_MOVE_ALLOWED)
324:                            .equals("false"))
325:                        continue;
326:
327:                    // now check nodes in lower position to see if they "hopped" here
328:                    // or if they have similar precedence and came from another parent.
329:
330:                    for (int j = 0; j < i; j++) {
331:                        NodeInfo niSib = (NodeInfo) order.get(j);
332:
333:                        // skip lower precedence nodes from this parent. These will get
334:                        // bumped during the lower precedence check
335:                        if (niSib.precedence == Precedence.getUserPrecedence())
336:                            continue;
337:
338:                        if (niSib.precedence.isEqualTo(ni.precedence)
339:                                && (niSib.indexInCVP == -1 || // from another parent
340:                                ni.indexInCVP < niSib.indexInCVP)) // niSib hopping left
341:                            return true;
342:                    }
343:
344:                    // now check upper positioned nodes to see if they "hopped"
345:
346:                    for (int j = i + 1; j < order.size(); j++) {
347:                        NodeInfo niSib = (NodeInfo) order.get(j);
348:
349:                        // ignore nodes from other parents and user precedence nodes
350:                        if (niSib.indexInCVP == -1
351:                                || niSib.precedence == Precedence
352:                                        .getUserPrecedence())
353:                            continue;
354:
355:                        if (ni.indexInCVP > niSib.indexInCVP && // niSib hopped right
356:                                niSib.precedence.isEqualTo(ni.precedence))
357:                            return true;
358:                    }
359:                }
360:                return false;
361:            }
362:
363:            /**
364:               This method scans through the nodes in the ordered list and identifies
365:               those that are not in the passed in compViewParent. For those it then
366:               looks in its current parent and checks to see if there are any down-
367:               stream (higher sibling index) siblings that have moveAllowed="false".
368:               If any such sibling is found then the node is not allowed to be
369:               reparented and is removed from the list.
370:             */
371:            static void applyNoReparenting(ArrayList order,
372:                    Element compViewParent, Element positionSet) {
373:                int i = 0;
374:                while (i < order.size()) {
375:                    NodeInfo ni = (NodeInfo) order.get(i);
376:                    if (!ni.node.getParentNode().equals(compViewParent)) {
377:                        ni.differentParent = true;
378:                        if (isNotReparentable(ni)) {
379:                            // this node should not be reparented. If it was placed
380:                            // here by way of a position directive then delete that
381:                            // directive out of the ni and posSet will be updated later
382:                            ni.positionDirective = null;
383:
384:                            // now we need to remove it from the ordering list but
385:                            // skip incrementing i, deleted ni now filled by next ni
386:                            order.remove(i);
387:                            continue;
388:                        }
389:                    }
390:                    i++;
391:                }
392:            }
393:
394:            /**
395:               Return true if the passed in node or any of its up-stream (higher index
396:               siblings have moveAllowed="false".
397:             */
398:            private static boolean isNotReparentable(NodeInfo ni) {
399:                if (ni.node.getAttribute(Constants.ATT_MOVE_ALLOWED).equals(
400:                        "false"))
401:                    return true;
402:
403:                Precedence nodePrec = ni.precedence;
404:                Element node = (Element) ni.node.getNextSibling();
405:
406:                while (node != null) {
407:                    if (node.getAttribute(Constants.ATT_MOVE_ALLOWED).equals(
408:                            "false")) {
409:                        Precedence p = Precedence.newInstance(node
410:                                .getAttribute(Constants.ATT_FRAGMENT));
411:                        if (nodePrec.isEqualTo(p))
412:                            return true;
413:                    }
414:                    node = (Element) node.getNextSibling();
415:                }
416:                return false;
417:            }
418:
419:            /**
420:               This method assembles in the passed in order object a list of NodeInfo
421:               objects ordered first by those specified in the position set and whose
422:               nodes still exist in the composite view and then by any remaining
423:               children in the compViewParent.
424:             */
425:            static void applyOrdering(ArrayList order, Element compViewParent,
426:                    Element positionSet) {
427:                // first pull out all visible channel or visible folder children and
428:                // put their id's in a list of available children and record their
429:                // relative order in the CVP.
430:
431:                ArrayList available = new ArrayList();
432:
433:                Element child = (Element) compViewParent.getFirstChild();
434:                Element next = null;
435:                int indexInCVP = 0;
436:
437:                while (child != null) {
438:                    next = (Element) child.getNextSibling();
439:
440:                    if (child.getAttribute("hidden").equals("false")
441:                            && (!child.getAttribute("chanID").equals("") || child
442:                                    .getAttribute("type").equals("regular")))
443:                        available.add(new NodeInfo(child, indexInCVP++));
444:                    child = next;
445:                }
446:
447:                // now fill the order list using id's from the position set if nodes
448:                // having those ids exist in the composite view. Otherwise discard
449:                // that position directive. As they are added to the list remove them
450:                // from the available nodes in the parent.
451:
452:                Document CV = compViewParent.getOwnerDocument();
453:                Element directive = (Element) positionSet.getFirstChild();
454:
455:                while (directive != null) {
456:                    next = (Element) directive.getNextSibling();
457:
458:                    // id of child to move is in the name attrib on the position nodes
459:                    String id = directive.getAttribute("name");
460:                    child = CV.getElementById(id);
461:
462:                    if (child != null) {
463:                        // look for the NodeInfo for this node in the available
464:                        // nodes and if found use that one. Otherwise use a new that
465:                        // does not include an index in the CVP parent. In either case
466:                        // indicate the position directive responsible for placing this
467:                        // NodeInfo object in the list.
468:
469:                        int idx = 0;
470:                        boolean found = false;
471:
472:                        while (!found && idx < available.size()) {
473:                            if (((NodeInfo) available.get(idx)).node == child)
474:                                found = true;
475:                            else
476:                                idx++;
477:                        }
478:                        NodeInfo ni = (found ? (NodeInfo) available.remove(idx)
479:                                : new NodeInfo(child));
480:                        ni.positionDirective = directive;
481:                        order.add(ni);
482:                    }
483:                    directive = next;
484:                }
485:
486:                // now append any remaining ids from the available list maintaining
487:                // the order that they have there.
488:
489:                for (int i = 0; i < available.size(); i++)
490:                    order.add(available.get(i));
491:            }
492:
493:            /**
494:               This method updates the positions recorded in a position set to reflect
495:               the ids of the nodes in the composite view of the layout. Any position
496:               nodes already in existence are reused to reduce database interaction
497:               needed to generate a new ID attribute. If any are left over after
498:               updating those position elements are removed. If no position set existed
499:               a new one is created for the parent. If no ILF nodes are found in the
500:               parent node then the position set as a whole is reclaimed.
501:             */
502:            public static void updatePositionSet(Element compViewParent,
503:                    Element plfParent, IPerson person) throws PortalException {
504:                if (LOG.isDebugEnabled())
505:                    LOG.debug("Updating Position Set");
506:
507:                if (compViewParent.getChildNodes().getLength() == 0) {
508:                    // no nodes to position. if set exists reclaim the space.
509:                    if (LOG.isDebugEnabled())
510:                        LOG.debug("No Nodes to position");
511:                    Element positions = getPositionSet(plfParent, person, false);
512:                    if (positions != null)
513:                        plfParent.removeChild(positions);
514:                    return;
515:                }
516:                Element posSet = (Element) getPositionSet(plfParent, person,
517:                        true);
518:                Element position = (Element) posSet.getFirstChild();
519:                Element viewNode = (Element) compViewParent.getFirstChild();
520:                boolean ilfNodesFound = false;
521:
522:                while (viewNode != null) {
523:                    String ID = viewNode.getAttribute(Constants.ATT_ID);
524:                    String channelId = viewNode
525:                            .getAttribute(Constants.ATT_CHANNEL_ID);
526:                    String type = viewNode.getAttribute(Constants.ATT_TYPE);
527:                    String hidden = viewNode.getAttribute(Constants.ATT_HIDDEN);
528:
529:                    if (ID.startsWith(Constants.FRAGMENT_ID_USER_PREFIX))
530:                        ilfNodesFound = true;
531:
532:                    if (!channelId.equals("") || // its a channel node or
533:                            (type.equals("regular") && // a regular, visible folder
534:                            hidden.equals("false"))) {
535:                        if (position != null)
536:                            position.setAttribute(Constants.ATT_NAME, ID);
537:                        else
538:                            position = createAndAppendPosition(ID, posSet,
539:                                    person);
540:                        position = (Element) position.getNextSibling();
541:                    }
542:                    viewNode = (Element) viewNode.getNextSibling();
543:                }
544:
545:                if (ilfNodesFound == false) // only plf nodes, no pos set needed
546:                    plfParent.removeChild(posSet);
547:                else {
548:                    // reclaim any leftover positions
549:                    while (position != null) {
550:                        Element nextPos = (Element) position.getNextSibling();
551:                        posSet.removeChild(position);
552:                        position = nextPos;
553:                    }
554:                }
555:            }
556:
557:            /**
558:               This method locates the position set element in the child list of the
559:               passed in plfParent or if not found it will create one automatically
560:               and return it if the passed in create flag is true.
561:             */
562:            private static Element getPositionSet(Element plfParent,
563:                    IPerson person, boolean create) throws PortalException {
564:                Node child = plfParent.getFirstChild();
565:
566:                while (child != null) {
567:                    if (child.getNodeName().equals(Constants.ELM_POSITION_SET))
568:                        return (Element) child;
569:                    child = child.getNextSibling();
570:                }
571:                if (create == false)
572:                    return null;
573:
574:                String ID = null;
575:
576:                try {
577:                    ID = getDLS().getNextStructDirectiveId(person);
578:                } catch (Exception e) {
579:                    throw new PortalException("Exception encountered while "
580:                            + "generating new position set node "
581:                            + "Id for userId=" + person.getID(), e);
582:                }
583:                Document plf = plfParent.getOwnerDocument();
584:                Element positions = plf
585:                        .createElement(Constants.ELM_POSITION_SET);
586:                positions.setAttribute(Constants.ATT_TYPE,
587:                        Constants.ELM_POSITION_SET);
588:                positions.setAttribute(Constants.ATT_ID, ID);
589:                plfParent.appendChild(positions);
590:                return positions;
591:            }
592:
593:            /**
594:               Create, append to the passed in position set, and return a position
595:               element that references the passed in elementID.
596:             */
597:            private static Element createAndAppendPosition(String elementID,
598:                    Element positions, IPerson person) throws PortalException {
599:                if (LOG.isDebugEnabled())
600:                    LOG.debug("Adding Position Set entry " + elementID + ".");
601:
602:                String ID = null;
603:
604:                try {
605:                    ID = getDLS().getNextStructDirectiveId(person);
606:                } catch (Exception e) {
607:                    throw new PortalException("Exception encountered while "
608:                            + "generating new position node "
609:                            + "Id for userId=" + person.getID(), e);
610:                }
611:                Document plf = positions.getOwnerDocument();
612:                Element position = plf.createElement(Constants.ELM_POSITION);
613:                position.setAttribute(Constants.ATT_TYPE,
614:                        Constants.ELM_POSITION);
615:                position.setAttribute(Constants.ATT_ID, ID);
616:                position.setAttributeNS(Constants.NS_URI, Constants.ATT_NAME,
617:                        elementID);
618:                positions.appendChild(position);
619:                return position;
620:            }
621:
622:            static class NodeInfoComparator implements  Comparator {
623:                public int compare(Object o1, Object o2) {
624:                    return ((NodeInfo) o1).indexInCVP
625:                            - ((NodeInfo) o2).indexInCVP;
626:                }
627:            }
628:
629:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.