Source Code Cross Referenced for FxGroupData.java in  » J2EE » fleXive » com » flexive » shared » content » 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 » J2EE » fleXive » com.flexive.shared.content 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /***************************************************************
002:         *  This file is part of the [fleXive](R) project.
003:         *
004:         *  Copyright (c) 1999-2008
005:         *  UCS - unique computing solutions gmbh (http://www.ucs.at)
006:         *  All rights reserved
007:         *
008:         *  The [fleXive](R) project is free software; you can redistribute
009:         *  it and/or modify it under the terms of the GNU General Public
010:         *  License as published by the Free Software Foundation;
011:         *  either version 2 of the License, or (at your option) any
012:         *  later version.
013:         *
014:         *  The GNU General Public License can be found at
015:         *  http://www.gnu.org/copyleft/gpl.html.
016:         *  A copy is found in the textfile GPL.txt and important notices to the
017:         *  license from the author are found in LICENSE.txt distributed with
018:         *  these libraries.
019:         *
020:         *  This library is distributed in the hope that it will be useful,
021:         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
022:         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023:         *  GNU General Public License for more details.
024:         *
025:         *  For further information about UCS - unique computing solutions gmbh,
026:         *  please see the company website: http://www.ucs.at
027:         *
028:         *  For further information about [fleXive](R), please see the
029:         *  project website: http://www.flexive.org
030:         *
031:         *
032:         *  This copyright notice MUST APPEAR in all copies of the file!
033:         ***************************************************************/package com.flexive.shared.content;
034:
035:        import com.flexive.shared.CacheAdmin;
036:        import com.flexive.shared.FxContext;
037:        import com.flexive.shared.XPathElement;
038:        import com.flexive.shared.exceptions.*;
039:        import com.flexive.shared.security.UserTicket;
040:        import com.flexive.shared.structure.*;
041:        import com.flexive.shared.value.FxReference;
042:        import com.flexive.shared.value.FxValue;
043:        import org.apache.commons.lang.ArrayUtils;
044:
045:        import java.util.ArrayList;
046:        import java.util.List;
047:
048:        /**
049:         * FxData extension for groups
050:         *
051:         * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
052:         */
053:        public class FxGroupData extends FxData implements  Cloneable {
054:            private static final long serialVersionUID = 133412774300450631L;
055:            private List<FxData> data;
056:
057:            public FxGroupData(String xpPrefix, String alias, int index,
058:                    String xPath, String xPathFull, int[] indices,
059:                    long assignmentId, FxMultiplicity assignmentMultiplicity,
060:                    int pos, FxGroupData parent, List<FxData> data,
061:                    boolean systemInternal) throws FxInvalidParameterException {
062:                super (xpPrefix, alias, index, xPath, xPathFull, indices,
063:                        assignmentId, assignmentMultiplicity, pos, parent,
064:                        systemInternal);
065:                this .data = data;
066:            }
067:
068:            /**
069:             * {@inheritDoc}
070:             */
071:            @Override
072:            public boolean isProperty() {
073:                return false;
074:            }
075:
076:            /**
077:             * {@inheritDoc}
078:             */
079:            @Override
080:            public boolean isGroup() {
081:                return true;
082:            }
083:
084:            /**
085:             * Get all child entries for this group
086:             *
087:             * @return child entries
088:             */
089:            public List<FxData> getChildren() {
090:                return data;
091:            }
092:
093:            /**
094:             * {@inheritDoc}
095:             */
096:            @Override
097:            public boolean isEmpty() {
098:                for (FxData curr : this .getChildren())
099:                    if (!curr.isEmpty())
100:                        return false;
101:                return true;
102:            }
103:
104:            /**
105:             * Helper to create a virtual root group
106:             *
107:             * @param xpPrefix XPath prefix like "FxType name[@pk=..]"
108:             * @return virtual root group
109:             * @throws FxInvalidParameterException on errors
110:             */
111:            public static FxGroupData createVirtualRootGroup(String xpPrefix)
112:                    throws FxInvalidParameterException {
113:                return new FxGroupData(xpPrefix, "", 1, "/", "/", new int[0],
114:                        -1, new FxMultiplicity(1, 1), -1, null,
115:                        new ArrayList<FxData>(10), false);
116:            }
117:
118:            /**
119:             * Move a child element identified by its alias and multiplicity by delta positions within this group
120:             * If delta is Integer.MAX_VALUE the data will always be placed at the bottom,
121:             * Integer.MIN_VALUE will always place it at the top.
122:             *
123:             * @param xp    element to move
124:             * @param delta delta positions to move
125:             */
126:            public void moveChild(XPathElement xp, int delta) {
127:                if (delta == 0 || data.size() < 2)
128:                    return;
129:                int currPos = -1, newPos;
130:                FxData child = null;
131:                List<String> aliases = new ArrayList<String>(
132:                        (int) (data.size() * 0.7));
133:                for (int i = 0; i < data.size(); i++) {
134:                    child = data.get(i);
135:                    if (!aliases.contains(child.getAlias()))
136:                        aliases.add(child.getAlias());
137:                    if (child.getXPathElement().equals(xp)) {
138:                        currPos = i;
139:                        break;
140:                    }
141:                }
142:                if (currPos == -1)
143:                    throw new FxNotFoundException("ex.xpath.alias.notFound", xp)
144:                            .asRuntimeException();
145:
146:                newPos = currPos + delta;
147:                if (newPos < 0)
148:                    newPos = 0; //move to top
149:                if (newPos >= data.size())
150:                    newPos = data.size() - 1; //move to bottom
151:                data.remove(currPos);
152:                data.add(newPos, child);
153:                //resync positions and indices
154:                for (int i = 0; i < data.size(); i++) {
155:                    data.get(i).setPos(i);
156:                    if (aliases.contains(data.get(i).getAlias())) {
157:                        //make sure to sync the multiplicity for each alias only once
158:                        data.get(i).compact();
159:                        aliases.remove(data.get(i).getAlias());
160:                    }
161:                }
162:
163:            }
164:
165:            /**
166:             * Add a child FxData at the correct position
167:             *
168:             * @param child FxData to add
169:             * @return the child
170:             */
171:            public synchronized FxData addChild(FxData child) {
172:                if (data.contains(child)) //TODO: change to containsChild()?
173:                    return child;
174:                int pos = (data.size() == 0 ? 0 : child.getPos());
175:                switch (child.getPos()) {
176:                case POSITION_TOP:
177:                    pos = 0;
178:                    break;
179:                case POSITION_BOTTOM:
180:                    pos = data.size();
181:                    break;
182:                }
183:                if (!child.isSystemInternal() && pos < 20
184:                        && child.getParent().isRootGroup())
185:                    pos = 20;
186:                child.setPos(pos);
187:                //check if the position is taken (if so move the child and successors at the given position one place down)
188:                for (int i = 0; i < data.size(); i++) {
189:                    if (data.get(i).getPos() < pos)
190:                        continue;
191:                    if (data.get(i).getPos() > pos) {
192:                        if (i > 0 && data.get(i - 1).getPos() < pos)
193:                            data.add(i, child);
194:                        else
195:                            data.add((i - 1 < 0 ? 0 : i - 1), child);
196:                        return child;
197:                    }
198:                    if (data.get(i).getPos() == pos) {
199:                        //move successors down
200:                        int lastPos = pos + 1;
201:                        data.get(i).setPos(lastPos);
202:                        for (int j = i + 1; j < data.size(); j++) {
203:                            if (!(data.get(j).getPos() > lastPos))
204:                                data.get(j).setPos(lastPos + 1);
205:                            lastPos = data.get(j).getPos();
206:                        }
207:                    }
208:                }
209:                data.add(child); //add at bottom
210:                return child;
211:            }
212:
213:            /**
214:             * Add an and FxData entry with the given XPath to this group (must be a direct child of this group, no nesting allowed!).
215:             * Empty groups consist of empty but preinitialized elements!
216:             *
217:             * @param xPath XPath to add to this group (must be a direct child of this group, no nesting allowed!)
218:             * @param pos   position in same hierarchy level
219:             * @return the added data element
220:             * @throws FxInvalidParameterException on errors
221:             * @throws FxNoAccessException         on errors
222:             * @throws FxNotFoundException         on errors
223:             * @throws FxCreateException           on errors
224:             */
225:            public FxData addEmptyChild(String xPath, int pos)
226:                    throws FxInvalidParameterException, FxNoAccessException,
227:                    FxNotFoundException, FxCreateException {
228:                FxType type;
229:                List<FxAssignment> childAssignments;
230:                if (this .isRootGroup()) {
231:                    type = CacheAdmin.getEnvironment().getAssignment(
232:                            this .getChildren().get(0).getAssignmentId())
233:                            .getAssignedType();
234:                    childAssignments = type.getConnectedAssignments("/");
235:                } else {
236:                    type = CacheAdmin.getEnvironment().getAssignment(
237:                            this .getAssignmentId()).getAssignedType();
238:                    childAssignments = ((FxGroupAssignment) type
239:                            .getAssignment(this .getXPath())).getAssignments();
240:                }
241:                if (childAssignments != null && childAssignments.size() > 0) {
242:                    FxGroupAssignment this Group = childAssignments.get(0)
243:                            .getParentGroupAssignment();
244:                    boolean isOneOf = false;
245:                    if (this Group != null)
246:                        isOneOf = this Group.getMode() == GroupMode.OneOf;
247:
248:                    String xPathNoMult = type.getName().toUpperCase()
249:                            + XPathElement.stripType(XPathElement
250:                                    .toXPathNoMult(xPath));
251:                    for (FxAssignment as : childAssignments) {
252:                        if (as.getXPath().equals(xPathNoMult)) {
253:                            if (isOneOf) {
254:                                //check if other assignments exist
255:                                for (FxData child : this .getChildren()) {
256:                                    if (child.getAssignmentId() != as.getId())
257:                                        throw new FxCreateException(
258:                                                "ex.content.xpath.group.oneof",
259:                                                as.getXPath(), this 
260:                                                        .getXPathFull())
261:                                                .setAffectedXPath(xPath);
262:                                }
263:                            }
264:                            int index = XPathElement.lastElement(xPath)
265:                                    .getIndex();
266:                            if (as.getMultiplicity().isValid(index))
267:                                return this .addChild(as.createEmptyData(this ,
268:                                        index).setPos(pos));
269:                            else
270:                                throw new FxInvalidParameterException("pos",
271:                                        "ex.content.xpath.index.invalid",
272:                                        index, as.getMultiplicity(), this 
273:                                                .getXPath())
274:                                        .setAffectedXPath(xPath);
275:                        }
276:                    }
277:                }
278:                throw new FxNotFoundException("ex.content.xpath.add.notFound",
279:                        xPath);
280:            }
281:
282:            /**
283:             * Apply the multiplicity to XPath and children if its a group
284:             */
285:            @Override
286:            protected void applyIndices() {
287:                try {
288:                    List<XPathElement> elements = XPathElement.split(this 
289:                            .getXPathFull());
290:                    if (elements.get(elements.size() - 1).getIndex() == this 
291:                            .getIndex())
292:                        return;
293:                    int pos = elements.size() - 1;
294:                    elements.get(pos).setIndex(this .getIndex());
295:                    this .XPathFull = XPathElement.toXPath(elements);
296:                    this .indices = XPathElement.getIndices(this .XPathFull);
297:                    if (this .getChildren() != null)
298:                        _changeIndex(this .getChildren(), pos, this .getIndex());
299:                } catch (FxInvalidParameterException e) {
300:                    throw e.asRuntimeException();
301:                }
302:            }
303:
304:            /**
305:             * 'Fix' the indices of children after they have been added to reflect the parent groups index in
306:             * their XPath
307:             *
308:             */
309:            public void fixChildIndices() {
310:                try {
311:                    List<XPathElement> elements = XPathElement.split(this 
312:                            .getXPathFull());
313:                    int pos = elements.size() - 1;
314:                    if (this .getChildren() != null)
315:                        _changeIndex(this .getChildren(), pos, this .getIndex());
316:                } catch (FxInvalidParameterException e) {
317:                    throw e.asRuntimeException();
318:                }
319:            }
320:
321:            /**
322:             * Recursively change the index for an element in the XPath of all children and their sub groups/properties
323:             *
324:             * @param children array of FxData to process
325:             * @param pos      position of the element to change in the XPath
326:             * @param index    the index to apply
327:             * @throws FxInvalidParameterException on errors with XPath composition
328:             */
329:            private void _changeIndex(List<FxData> children, int pos, int index)
330:                    throws FxInvalidParameterException {
331:                List<XPathElement> elements;
332:                for (FxData curr : children) {
333:                    elements = XPathElement.split(curr.getXPath());
334:                    elements.get(pos).setIndex(index);
335:                    curr.XPathFull = XPathElement.toXPath(elements);
336:                    curr.indices = XPathElement.getIndices(curr.XPathFull);
337:                    if (curr instanceof  FxGroupData)
338:                        _changeIndex(((FxGroupData) curr).getChildren(), pos,
339:                                index);
340:                }
341:            }
342:
343:            /**
344:             * Remove all empty entries of this group that are not required
345:             *
346:             * @see #removeEmptyEntries(boolean)
347:             */
348:            public void removeEmptyEntries() {
349:                removeEmptyEntries(false);
350:            }
351:
352:            /**
353:             * Remove all empty entries of this group
354:             *
355:             * @param includeRequired include entries that are required?
356:             */
357:            public void removeEmptyEntries(boolean includeRequired) {
358:                for (FxData curr : data)
359:                    if (curr.isEmpty()
360:                            && (curr.isGroup() || includeRequired || curr
361:                                    .isRemoveable())
362:                            && !curr.isSystemInternal()) {
363:                        data.remove(curr);
364:                        for (FxData com : data) {
365:                            if (com.getAssignmentId() == curr.getAssignmentId()) {
366:                                com.compact();
367:                                break;
368:                            }
369:                        }
370:                        removeEmptyEntries(includeRequired);
371:                        return;
372:                    } else if (curr instanceof  FxGroupData) {
373:                        ((FxGroupData) curr)
374:                                .removeEmptyEntries(includeRequired);
375:                    }
376:            }
377:
378:            /**
379:             * Synchronize positions closing gaps optionally including sub groups
380:             *
381:             * @param includeSubGroups close gaps for subgroups as well?
382:             */
383:            public void compactPositions(boolean includeSubGroups) {
384:                int pos = 0;
385:                for (FxData curr : data) {
386:                    curr.setPos(pos++);
387:                    if (includeSubGroups && curr instanceof  FxGroupData)
388:                        ((FxGroupData) curr).compactPositions(true);
389:                }
390:            }
391:
392:            /**
393:             * Get the root group for this group
394:             *
395:             * @return root group
396:             */
397:            private FxGroupData getRootGroup() {
398:                FxGroupData root = this ;
399:                while (root.getParent() != null)
400:                    root = root.getParent();
401:                return root;
402:            }
403:
404:            /**
405:             * Is this group the root group?
406:             *
407:             * @return if this group is the root group
408:             */
409:            public boolean isRootGroup() {
410:                return this .getAssignmentId() == -1;
411:            }
412:
413:            /**
414:             * Get the group denoted by the given XPath
415:             *
416:             * @param xPath requested XPath for the group
417:             * @return FxGroupData
418:             * @throws FxNotFoundException         if no group with this XPath is found
419:             * @throws FxInvalidParameterException if the XPath is invalid
420:             */
421:            public FxGroupData getGroup(String xPath)
422:                    throws FxNotFoundException, FxInvalidParameterException {
423:                FxGroupData root = getRootGroup();
424:                if ("/".equals(xPath))
425:                    return root;
426:                List<XPathElement> elements = XPathElement.split(xPath);
427:
428:                FxGroupData found = null;
429:                List<FxData> currGroup = root.getChildren();
430:                for (XPathElement e : elements) {
431:                    found = null;
432:                    for (FxData curr : currGroup) {
433:                        if (curr instanceof  FxGroupData
434:                                && curr.getXPathElement().equals(e)) {
435:                            found = (FxGroupData) curr;
436:                            currGroup = found.getChildren();
437:                            break;
438:                        }
439:                    }
440:                    if (found == null)
441:                        throw new FxNotFoundException(
442:                                "ex.content.xpath.notFound", xPath);
443:                }
444:                if (found == null)
445:                    throw new FxNotFoundException("ex.content.xpath.notFound",
446:                            xPath);
447:                return found;
448:            }
449:
450:            /**
451:             * Add a property at the given XPath location, removing eventually existing properties.
452:             * The group for this property has to exist already!
453:             *
454:             * @param xPath      requested XPath
455:             * @param assignment assignment of the property
456:             * @param value      value
457:             * @param pos        position
458:             * @throws FxInvalidParameterException if the XPath is invalid
459:             * @throws FxNotFoundException         if the parent group does not exist
460:             */
461:            public void addProperty(String xPath,
462:                    FxPropertyAssignment assignment, FxValue value, int pos)
463:                    throws FxInvalidParameterException, FxNotFoundException {
464:                FxGroupData parentGroup = this ;
465:                List<XPathElement> elements = XPathElement.split(xPath);
466:                if (elements.size() > 1) {
467:                    String groupXPath = XPathElement.toXPath(elements.subList(
468:                            0, elements.size() - 1));
469:                    parentGroup = getGroup(groupXPath);
470:                }
471:                int index = elements.get(elements.size() - 1).getIndex();
472:                FxPropertyData data = new FxPropertyData(this .xpPrefix,
473:                        assignment.getAlias(), index, XPathElement
474:                                .stripType(XPathElement.toXPathNoMult(xPath)),
475:                        xPath, XPathElement.getIndices(xPath), assignment
476:                                .getId(), assignment.getProperty().getId(),
477:                        assignment.getMultiplicity(), pos, parentGroup, value,
478:                        assignment.isSystemInternal());
479:
480:                FxData check = parentGroup
481:                        .containsChild(data.getXPathElement());
482:                if (check != null)
483:                    parentGroup.data.remove(check);
484:                parentGroup.addChild(data);
485:                /*boolean added = false;
486:                for (int i = 0; i < parentGroup.data.size(); i++) {
487:                    if (parentGroup.data.get(i).getPos() > data.getPos()) {
488:                        parentGroup.data.add(i, data);
489:                        added = true;
490:                        break;
491:                    }
492:                }
493:                if (!added) //add at end
494:                    parentGroup.data.add(data);*/
495:                //            parentGroup.replaceChild(data.getXPathElement(), data);
496:                //        } else { //TODO: check if adding allowed!
497:                //            parentGroup.data.add(pos, data);
498:                //        }
499:            }
500:
501:            /**
502:             * Check if a child with the same alias and multiplicity that is not empty exists.
503:             * No elements of subgroups are checked, just <i>direct</i> childs!
504:             *
505:             * @param check XPathElement to check
506:             * @return FxData or <code>null</code>
507:             */
508:            public FxData containsChild(XPathElement check) {
509:                for (FxData curr : getChildren()) {
510:                    if (curr.getXPathElement().equals(check))
511:                        return curr;
512:                }
513:                return null;
514:            }
515:
516:            public void replaceChild(XPathElement xpath, FxData data) {
517:                for (int i = 0; i < this .data.size(); i++) {
518:                    if (this .data.get(i).getXPathElement().equals(xpath)) {
519:                        this .data.set(i, data);
520:                        return;
521:                    }
522:                }
523:            }
524:
525:            /**
526:             * Add a group entry at the given XPath. Existing entries will stay untouched but position adjusted.
527:             * If parent groups of this group do not exist, they will be created as well.
528:             *
529:             * @param xPath             requested XPath
530:             * @param fxGroupAssignment the assignment of the group
531:             * @param pos               position
532:             * @throws FxInvalidParameterException on errors
533:             * @throws FxNotFoundException         on errors
534:             * @throws FxCreateException           on errors
535:             */
536:            public void addGroup(String xPath,
537:                    FxGroupAssignment fxGroupAssignment, int pos)
538:                    throws FxInvalidParameterException, FxNotFoundException,
539:                    FxCreateException {
540:                if (xPath.endsWith("/"))
541:                    xPath = xPath.substring(0, xPath.length() - 1);
542:                List<XPathElement> xp = XPathElement.split(xPath);
543:                XPathElement addy = xp.get(xp.size() - 1);
544:                FxGroupData currGroup = getRootGroup(), tmp;
545:                //        System.out.println("adding group(s): " + xPath);
546:                for (XPathElement curr : xp) {
547:                    if ((tmp = (FxGroupData) currGroup.containsChild(curr)) != null) {
548:                        currGroup = tmp;
549:                    } else {
550:                        FxGroupAssignment gaNew = (FxGroupAssignment) fxGroupAssignment
551:                                .getAssignedType().getAssignment(
552:                                        XPathElement.buildXPath(true, currGroup
553:                                                .getXPath(), curr.getAlias()));
554:                        FxData gdNew = gaNew.createEmptyData(currGroup, curr
555:                                .getIndex());
556:                        //TODO: check if adding allowed here!
557:                        //                System.out.println("creating " + curr + " in " + xPath);
558:                        if (addy.equals(curr)) {
559:                            //                    System.out.println("creating the actual addy group...");
560:                            gdNew.setPos(pos);
561:                        }
562:                        currGroup.addChild(gdNew);
563:                        currGroup = currGroup.getGroup(gdNew.getXPathFull());
564:                    }
565:                }
566:            }
567:
568:            /**
569:             * Remove the requested child data and compact indices and positions
570:             *
571:             * @param data FxData to remove
572:             * @throws FxInvalidParameterException on errors
573:             * @throws FxNoAccessException         on errors
574:             */
575:            public void removeChild(FxData data)
576:                    throws FxInvalidParameterException, FxNoAccessException {
577:                if (!data.isRemoveable())
578:                    throw new FxNoAccessException(
579:                            "ex.content.xpath.remove.invalid", data
580:                                    .getXPathFull());
581:
582:                if (!this .data.remove(data)) //was: if (!data.getParent().data.remove(data))
583:                    throw new FxInvalidParameterException(
584:                            "ex.content.xpath.remove.notFound", data
585:                                    .getXPathFull());
586:
587:                data.compact();
588:                compactPositions(false);
589:            }
590:
591:            /**
592:             * "Explode" this group by adding all createable assignments at the bottom
593:             *
594:             * @param explodeChildGroups recursively explode all <i>existing</i> child groups?
595:             */
596:            public void explode(boolean explodeChildGroups) {
597:                for (String xpath : getCreateableChildren(false))
598:                    try {
599:                        addEmptyChild(xpath, POSITION_BOTTOM);
600:                    } catch (FxApplicationException e) {
601:                        throw e.asRuntimeException();
602:                    }
603:                if (explodeChildGroups) {
604:                    // explode child groups
605:                    for (FxData child : getChildren()) {
606:                        if (child.isGroup()) {
607:                            ((FxGroupData) child).explode(true);
608:                        }
609:                    }
610:                }
611:            }
612:
613:            /**
614:             * Get a list of child FxData instances (as XPath with full indices) that can be created as children for this group.
615:             * Readonly or no access properties or groups will not be returned!
616:             *
617:             * @param includeExisting include entries for children that already exist but with a new (higher) multiplicity?
618:             * @return List of XPaths
619:             */
620:            public List<String> getCreateableChildren(boolean includeExisting) {
621:                List<String> ret = new ArrayList<String>(20);
622:                FxType type;
623:                List<FxAssignment> childAssignments;
624:                boolean checkOneOf;
625:                try {
626:                    if (this .isRootGroup()) {
627:                        type = CacheAdmin.getEnvironment().getAssignment(
628:                                this .getChildren().get(0).getAssignmentId())
629:                                .getAssignedType();
630:                        childAssignments = type.getConnectedAssignments("/");
631:                        checkOneOf = false;
632:                    } else {
633:                        type = CacheAdmin.getEnvironment().getAssignment(
634:                                this .getAssignmentId()).getAssignedType();
635:                        FxGroupAssignment this Assignment = ((FxGroupAssignment) type
636:                                .getAssignment(this .getXPath()));
637:                        childAssignments = this Assignment.getAssignments();
638:                        checkOneOf = this Assignment.getMode() == GroupMode.OneOf;
639:                    }
640:                } catch (FxApplicationException e) {
641:                    throw e.asRuntimeException();
642:                }
643:
644:                int count;
645:                for (FxAssignment as : childAssignments) {
646:                    if (!as.isEnabled() || as.isSystemInternal())
647:                        continue;
648:                    count = 0;
649:                    if (as instanceof  FxPropertyAssignment
650:                            && type.usePropertyPermissions()) {
651:                        UserTicket ticket = FxContext.get().getTicket();
652:                        long aclId = ((FxPropertyAssignment) as).getACL()
653:                                .getId();
654:                        //ignore owner in this checks since owner membership does not allow creation
655:                        if (!ticket.mayReadACL(aclId, 0)
656:                                || !ticket.mayCreateACL(aclId, 0)
657:                                || !ticket.mayEditACL(aclId, 0))
658:                            continue;
659:                    }
660:                    for (FxData _curr : this .getChildren()) {
661:                        if (_curr.getAssignmentId() == as.getId())
662:                            count++;
663:                    }
664:                    if (checkOneOf && count > 0) {
665:                        //one child exists already -> can only use this one
666:                        ret.clear();
667:                    }
668:                    try {
669:                        if (as.getMultiplicity().getMax() > count
670:                                && (includeExisting || (count == 0 && !includeExisting)))
671:                            ret.add(as.createEmptyData(this , count + 1)
672:                                    .getXPathFull());
673:                    } catch (Exception e) {
674:                        //ignore
675:                    }
676:                    if (checkOneOf && count > 0)
677:                        return ret; //now we either have another to add of an existing or none -> return
678:                }
679:                return ret;
680:            }
681:
682:            /**
683:             * {@inheritDoc}
684:             */
685:            @Override
686:            protected FxGroupData copy(FxGroupData parent) {
687:                FxGroupData clone;
688:                try {
689:                    clone = new FxGroupData(xpPrefix, getAlias(), getIndex(),
690:                            getXPath(), getXPathFull(), ArrayUtils
691:                                    .clone(getIndices()), getAssignmentId(),
692:                            getAssignmentMultiplicity(), getPos(), parent,
693:                            null, isSystemInternal());
694:                    List<FxData> cloneData = new ArrayList<FxData>(data.size());
695:                    for (FxData org : data)
696:                        cloneData.add(org.copy(clone));
697:                    clone.data = cloneData;
698:                } catch (FxInvalidParameterException e) {
699:                    throw e.asRuntimeException();
700:                }
701:                return clone;
702:            }
703:
704:            /**
705:             * Get a list of all FxReference values in this group and optionally all sub groups
706:             *
707:             * @param includeSubGroups collect FxReferences from sub groups as well?
708:             * @return list of all FxReference values in this group and optionally all sub groups
709:             */
710:            protected List<FxReference> getReferences(boolean includeSubGroups) {
711:                List<FxReference> refs = new ArrayList<FxReference>(20);
712:                gatherReferences(refs, includeSubGroups);
713:                return refs;
714:            }
715:
716:            /**
717:             * Walk through all data nodes and collect FxReference instances
718:             *
719:             * @param refs             list to add references to
720:             * @param includeSubGroups should sub groups be included?
721:             */
722:            private void gatherReferences(List<FxReference> refs,
723:                    boolean includeSubGroups) {
724:                for (FxData d : data) {
725:                    if (d instanceof  FxGroupData) {
726:                        if (includeSubGroups)
727:                            ((FxGroupData) d).gatherReferences(refs,
728:                                    includeSubGroups);
729:                    } else if (d instanceof  FxPropertyData) {
730:                        if (((FxPropertyData) d).getValue() instanceof  FxReference)
731:                            refs.add((FxReference) ((FxPropertyData) d)
732:                                    .getValue());
733:                    }
734:                }
735:            }
736:
737:            /**
738:             * Get a list of all FxPropertyData entries that are assigned to propertyId
739:             *
740:             * @param propertyId   the property id requested
741:             * @param includeEmpty include empty data instances?
742:             * @return list of all FxPropertyData entries that are assigned to propertyId
743:             */
744:            public List<FxPropertyData> getPropertyData(long propertyId,
745:                    boolean includeEmpty) {
746:                List<FxPropertyData> res = new ArrayList<FxPropertyData>(5);
747:                for (FxData d : getChildren()) {
748:                    if (d instanceof  FxPropertyData
749:                            && ((FxPropertyData) d).getPropertyId() == propertyId) {
750:                        if (includeEmpty || !d.isEmpty())
751:                            res.add((FxPropertyData) d);
752:                    } else if (d instanceof  FxGroupData)
753:                        res.addAll(((FxGroupData) d).getPropertyData(
754:                                propertyId, includeEmpty));
755:                }
756:                return res;
757:            }
758:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.