Source Code Cross Referenced for FxContent.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) 


0001:        /***************************************************************
0002:         *  This file is part of the [fleXive](R) project.
0003:         *
0004:         *  Copyright (c) 1999-2008
0005:         *  UCS - unique computing solutions gmbh (http://www.ucs.at)
0006:         *  All rights reserved
0007:         *
0008:         *  The [fleXive](R) project is free software; you can redistribute
0009:         *  it and/or modify it under the terms of the GNU General Public
0010:         *  License as published by the Free Software Foundation;
0011:         *  either version 2 of the License, or (at your option) any
0012:         *  later version.
0013:         *
0014:         *  The GNU General Public License can be found at
0015:         *  http://www.gnu.org/copyleft/gpl.html.
0016:         *  A copy is found in the textfile GPL.txt and important notices to the
0017:         *  license from the author are found in LICENSE.txt distributed with
0018:         *  these libraries.
0019:         *
0020:         *  This library is distributed in the hope that it will be useful,
0021:         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0022:         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0023:         *  GNU General Public License for more details.
0024:         *
0025:         *  For further information about UCS - unique computing solutions gmbh,
0026:         *  please see the company website: http://www.ucs.at
0027:         *
0028:         *  For further information about [fleXive](R), please see the
0029:         *  project website: http://www.flexive.org
0030:         *
0031:         *
0032:         *  This copyright notice MUST APPEAR in all copies of the file!
0033:         ***************************************************************/package com.flexive.shared.content;
0034:
0035:        import com.flexive.shared.CacheAdmin;
0036:        import com.flexive.shared.FxSharedUtils;
0037:        import com.flexive.shared.XPathElement;
0038:        import com.flexive.shared.exceptions.*;
0039:        import com.flexive.shared.interfaces.ContentEngine;
0040:        import com.flexive.shared.security.LifeCycleInfo;
0041:        import com.flexive.shared.structure.FxEnvironment;
0042:        import com.flexive.shared.structure.FxMultiplicity;
0043:        import com.flexive.shared.structure.FxPropertyAssignment;
0044:        import com.flexive.shared.structure.FxType;
0045:        import com.flexive.shared.value.*;
0046:        import org.apache.commons.lang.StringUtils;
0047:
0048:        import java.io.Serializable;
0049:        import java.util.ArrayList;
0050:        import java.util.Date;
0051:        import java.util.List;
0052:        import java.util.Random;
0053:
0054:        /**
0055:         * A content instance
0056:         *
0057:         * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
0058:         */
0059:        public class FxContent implements  Serializable, Cloneable {
0060:
0061:            private static final long serialVersionUID = -7014370829966212118L;
0062:
0063:            /**
0064:             * Topmost position for relation positioning
0065:             */
0066:            public final static int POSITION_TOP = Integer.MIN_VALUE;
0067:
0068:            /**
0069:             * Bottommost position for relation positioning
0070:             */
0071:            public final static int POSITION_BOTTOM = Integer.MAX_VALUE;
0072:            private FxPK pk;
0073:            private long typeId;
0074:            private long mandatorId;
0075:            private long aclId;
0076:            private long stepId;
0077:            private int maxVersion;
0078:            private int liveVersion;
0079:            private long mainLanguage;
0080:
0081:            private boolean active;
0082:
0083:            private int initialLiveVersion;
0084:            private boolean relation;
0085:            private FxPK relatedSource;
0086:            private FxPK relatedDestination;
0087:            private int relatedSourcePosition;
0088:
0089:            private int relatedDestinationPosition;
0090:
0091:            private LifeCycleInfo lifeCycleInfo;
0092:
0093:            private FxGroupData data;
0094:            private long binaryPreviewId;
0095:            private long binaryPreviewACL;
0096:
0097:            /**
0098:             * Constructor
0099:             *
0100:             * @param pk                         primary key
0101:             * @param typeId                     used type id
0102:             * @param relation                   is this a content for a relation?
0103:             * @param mandatorId                 mandator id
0104:             * @param aclId                      ACL id
0105:             * @param stepId                     step id
0106:             * @param maxVersion                 max. version for this instance
0107:             * @param liveVersion                live version for this instance (0=no live version exists)
0108:             * @param active                     is this instance active
0109:             * @param mainLanguage               main language
0110:             * @param relatedSource              related source instance (only if this is a relation)
0111:             * @param relatedDestination         related destination instance (only if this is a relation)
0112:             * @param relatedSourcePosition      position for source instance (only if this is a relation)
0113:             * @param relatedDestinationPosition position for destination instance (only if this is a relation)
0114:             * @param lifeCycleInfo              lifecycle
0115:             * @param data                       data
0116:             * @param binaryPreviewId            id of the preview binary
0117:             * @param binaryPreviewACL           id of the ACL of the preview binary
0118:             */
0119:            public FxContent(FxPK pk, long typeId, boolean relation,
0120:                    long mandatorId, long aclId, long stepId, int maxVersion,
0121:                    int liveVersion, boolean active, long mainLanguage,
0122:                    FxPK relatedSource, FxPK relatedDestination,
0123:                    int relatedSourcePosition, int relatedDestinationPosition,
0124:                    LifeCycleInfo lifeCycleInfo, FxGroupData data,
0125:                    long binaryPreviewId, long binaryPreviewACL) {
0126:                this .pk = pk;
0127:                this .typeId = typeId;
0128:                this .relation = relation;
0129:                this .mandatorId = mandatorId;
0130:                this .aclId = aclId;
0131:                this .stepId = stepId;
0132:                this .maxVersion = maxVersion;
0133:                this .liveVersion = liveVersion;
0134:                this .initialLiveVersion = liveVersion;
0135:                this .mainLanguage = mainLanguage;
0136:                this .relatedSource = relatedSource;
0137:                this .relatedDestination = relatedDestination;
0138:                this .relatedSourcePosition = relatedSourcePosition;
0139:                this .relatedDestinationPosition = relatedDestinationPosition;
0140:                this .lifeCycleInfo = lifeCycleInfo;
0141:                this .data = data;
0142:                this .active = active;
0143:                this .binaryPreviewId = binaryPreviewId;
0144:                this .binaryPreviewACL = binaryPreviewACL;
0145:            }
0146:
0147:            /**
0148:             * Getter for the primary key
0149:             *
0150:             * @return primary key
0151:             */
0152:            public FxPK getPk() {
0153:                return pk;
0154:            }
0155:
0156:            /**
0157:             * Getter for the Id
0158:             *
0159:             * @return id
0160:             */
0161:            public long getId() {
0162:                return pk.getId();
0163:            }
0164:
0165:            /**
0166:             * Getter for the version
0167:             *
0168:             * @return version
0169:             */
0170:            public int getVersion() {
0171:                return pk.getVersion();
0172:            }
0173:
0174:            /**
0175:             * Getter for the type id
0176:             *
0177:             * @return type id
0178:             */
0179:            public long getTypeId() {
0180:                return typeId;
0181:            }
0182:
0183:            /**
0184:             * Getter for the mandator id
0185:             *
0186:             * @return mandator id
0187:             */
0188:            public long getMandatorId() {
0189:                return mandatorId;
0190:            }
0191:
0192:            /**
0193:             * Getter for the ACL id
0194:             *
0195:             * @return ACL id
0196:             */
0197:            public long getAclId() {
0198:                return aclId;
0199:            }
0200:
0201:            /**
0202:             * Set the ACL id
0203:             *
0204:             * @param aclId the ACL id
0205:             */
0206:            public void setAclId(long aclId) {
0207:                this .aclId = aclId;
0208:                //TODO: check if ACL is valid!
0209:                updateSystemInternalProperties();
0210:            }
0211:
0212:            /**
0213:             * Getter for the step id
0214:             *
0215:             * @return step id
0216:             */
0217:            public long getStepId() {
0218:                return stepId;
0219:            }
0220:
0221:            /**
0222:             * Set the workflow step id
0223:             *
0224:             * @param stepId workflow step id
0225:             */
0226:            public void setStepId(long stepId) {
0227:                //TODO: check if step is valid
0228:                this .stepId = stepId;
0229:                if (CacheAdmin.getEnvironment().getStep(stepId).isLiveStep())
0230:                    this .liveVersion = this .getPk().getVersion();
0231:                else
0232:                    this .liveVersion = this .initialLiveVersion;
0233:                updateSystemInternalProperties();
0234:            }
0235:
0236:            /**
0237:             * Get the max version of this content
0238:             *
0239:             * @return max version of this content
0240:             */
0241:            public int getMaxVersion() {
0242:                return maxVersion;
0243:            }
0244:
0245:            /**
0246:             * Is this content instance the max version
0247:             *
0248:             * @return if content instance the max version
0249:             */
0250:            public boolean isMaxVersion() {
0251:                return pk.getVersion() == maxVersion || pk.isNew();
0252:            }
0253:
0254:            /**
0255:             * Get the live version of this content or 0 if no live version exists
0256:             *
0257:             * @return live version of this content or 0 if no live version exists
0258:             */
0259:            public int getLiveVersion() {
0260:                return liveVersion;
0261:            }
0262:
0263:            /**
0264:             * Is this content instance the live version
0265:             *
0266:             * @return if content instance the live version
0267:             */
0268:            public boolean isLiveVersion() {
0269:                return pk.getVersion() == liveVersion
0270:                        || (pk.isNew() && liveVersion == 1);
0271:            }
0272:
0273:            /**
0274:             * Checks if the given PK matches this content. This allows to match a generic PK (i.e. without
0275:             * a distinct version, but {@link FxPK#LIVE} or {@link FxPK#MAX}), which the FxPK equals method
0276:             * cannot do.
0277:             *
0278:             * @param otherPk   the PK to be matched
0279:             * @return  true if otherPk matches this content
0280:             */
0281:            public boolean matchesPk(FxPK otherPk) {
0282:                return pk.equals(otherPk)
0283:                        || (pk.getId() == otherPk.getId() && ((otherPk
0284:                                .getVersion() == FxPK.MAX && isMaxVersion()) || (otherPk
0285:                                .getVersion() == FxPK.LIVE && isLiveVersion())));
0286:            }
0287:
0288:            /**
0289:             * Get the main language
0290:             *
0291:             * @return main language
0292:             */
0293:            public long getMainLanguage() {
0294:                return mainLanguage;
0295:            }
0296:
0297:            /**
0298:             * Set the main language
0299:             *
0300:             * @param mainLanguage main language
0301:             */
0302:            public void setMainLanguage(long mainLanguage) {
0303:                this .mainLanguage = mainLanguage;
0304:                updateSystemInternalProperties();
0305:            }
0306:
0307:            /**
0308:             * Is this content active?
0309:             *
0310:             * @return content is active
0311:             */
0312:            public boolean isActive() {
0313:                return active;
0314:            }
0315:
0316:            /**
0317:             * (De-)activate this content
0318:             *
0319:             * @param active active flag
0320:             */
0321:            public void setActive(boolean active) {
0322:                this .active = active;
0323:                updateSystemInternalProperties();
0324:            }
0325:
0326:            /**
0327:             * Is this content a relation?
0328:             *
0329:             * @return content is relation
0330:             */
0331:            public boolean isRelation() {
0332:                return relation;
0333:            }
0334:
0335:            /**
0336:             * If this is a relation get the assigned "from" (or source) instance
0337:             *
0338:             * @return the assigned "from" (or source) instance
0339:             */
0340:            public FxPK getRelatedSource() {
0341:                return relatedSource;
0342:            }
0343:
0344:            /**
0345:             * Set the primary key of the source relation
0346:             *
0347:             * @param src source relation
0348:             * @return this
0349:             */
0350:            public FxContent setRelatedSource(FxPK src) {
0351:                this .relatedSource = src;
0352:                return this ;
0353:            }
0354:
0355:            /**
0356:             * If this is a relation get the assigned "to" (or destination) instance
0357:             *
0358:             * @return the assigned "to" (or destination) instance
0359:             */
0360:            public FxPK getRelatedDestination() {
0361:                return relatedDestination;
0362:            }
0363:
0364:            /**
0365:             * Set the primary key of the destination relation
0366:             *
0367:             * @param dst destination relation
0368:             * @return this
0369:             */
0370:            public FxContent setRelatedDestination(FxPK dst) {
0371:                this .relatedDestination = dst;
0372:                return this ;
0373:            }
0374:
0375:            /**
0376:             * Get the position for the source content instance
0377:             *
0378:             * @return position for the source content instance
0379:             */
0380:            public int getRelatedSourcePosition() {
0381:                return relatedSourcePosition;
0382:            }
0383:
0384:            /**
0385:             * Get the position for the destination content instance
0386:             *
0387:             * @return position for the destination content instance
0388:             */
0389:            public int getRelatedDestinationPosition() {
0390:                return relatedDestinationPosition;
0391:            }
0392:
0393:            public void setRelatedDestinationPosition(
0394:                    int relatedDestinationPosition) {
0395:                this .relatedDestinationPosition = relatedDestinationPosition;
0396:            }
0397:
0398:            /**
0399:             * Get the lifecycle information
0400:             *
0401:             * @return lifecycle information
0402:             */
0403:            public LifeCycleInfo getLifeCycleInfo() {
0404:                return lifeCycleInfo;
0405:            }
0406:
0407:            /**
0408:             * Get all FxData (Group or Property) entries for the given XPath
0409:             *
0410:             * @param XPath requested XPath
0411:             * @return FxData elements for the given XPath
0412:             * @throws FxInvalidParameterException for invalid XPath provided
0413:             * @throws FxNotFoundException         if no match was found
0414:             */
0415:            public List<FxData> getData(String XPath)
0416:                    throws FxInvalidParameterException, FxNotFoundException {
0417:                List<FxData> base = data.getChildren();
0418:                if (StringUtils.isEmpty(XPath) || "/".equals(XPath))
0419:                    return base;
0420:                List<FxData> ret = base;
0421:                boolean found;
0422:                for (XPathElement xpe : XPathElement.split(XPath.toUpperCase())) {
0423:                    found = false;
0424:                    for (FxData curr : ret) {
0425:                        if (curr.getXPathElement().equals(xpe)) {
0426:                            if (curr.isProperty()) {
0427:                                ret = new ArrayList<FxData>(1);
0428:                                ret.add(curr);
0429:                                return ret;
0430:                            } else {
0431:                                ret = ((FxGroupData) curr).getChildren();
0432:                                found = true;
0433:                                break;
0434:                            }
0435:                        }
0436:                    }
0437:                    if (!found)
0438:                        throw new FxNotFoundException(
0439:                                "ex.content.xpath.notFound", XPath);
0440:                }
0441:                return ret;
0442:            }
0443:
0444:            /**
0445:             * Get the FxPropertyData entry for the given XPath
0446:             *
0447:             * @param XPath requested XPath
0448:             * @return FxPropertyData entry for the given XPath
0449:             * @throws FxInvalidParameterException for invalid XPath provided or XPath is no property
0450:             * @throws FxNotFoundException         if no match was found
0451:             */
0452:            public FxPropertyData getPropertyData(String XPath)
0453:                    throws FxNotFoundException, FxInvalidParameterException {
0454:                FxSharedUtils.checkParameterEmpty(XPath, "XPATH");
0455:                XPath = XPathElement.stripType(XPath);
0456:                List<FxData> found = getData(XPath);
0457:                if (found.size() != 1
0458:                        || !(found.get(0) instanceof  FxPropertyData))
0459:                    throw new FxInvalidParameterException("XPATH",
0460:                            "ex.xpath.element.noProperty", XPath);
0461:                return (FxPropertyData) found.get(0);
0462:            }
0463:
0464:            /**
0465:             * Get a list of all FxPropertyData entries that are assigned to propertyId
0466:             *
0467:             * @param propertyId   the property id requested
0468:             * @param includeEmpty include empty data instances?
0469:             * @return list of all FxPropertyData entries that are assigned to propertyId
0470:             */
0471:            public List<FxPropertyData> getPropertyData(long propertyId,
0472:                    boolean includeEmpty) {
0473:                return getRootGroup().getPropertyData(propertyId, includeEmpty);
0474:            }
0475:
0476:            /**
0477:             * Get the FxGroupData entry for the given XPath
0478:             *
0479:             * @param XPath requested XPath
0480:             * @return FxGroupData entry for the given XPath
0481:             * @throws FxInvalidParameterException for invalid XPath provided or XPath is no property
0482:             * @throws FxNotFoundException         if no match was found
0483:             */
0484:            public FxGroupData getGroupData(String XPath)
0485:                    throws FxNotFoundException, FxInvalidParameterException {
0486:                FxSharedUtils.checkParameterEmpty(XPath, "XPATH");
0487:                XPath = XPathElement.stripType(XPathElement.toXPathMult(XPath
0488:                        .toUpperCase()));
0489:                //this is a slightly modified version of getData() but since groups may not contain children its safer
0490:                List<FxData> base = data.getChildren();
0491:                if (StringUtils.isEmpty(XPath) || "/".equals(XPath))
0492:                    return getRootGroup();
0493:                List<FxData> currChildren = base;
0494:                FxGroupData group = null;
0495:                boolean found;
0496:                for (XPathElement xpe : XPathElement.split(XPath.toUpperCase())) {
0497:                    found = false;
0498:                    for (FxData curr : currChildren) {
0499:                        if (curr.getXPathElement().equals(xpe)) {
0500:                            if (curr.isProperty()) {
0501:                                throw new FxInvalidParameterException("XPATH",
0502:                                        "ex.xpath.element.noGroup", XPath);
0503:                            } else {
0504:                                currChildren = ((FxGroupData) curr)
0505:                                        .getChildren();
0506:                                group = ((FxGroupData) curr);
0507:                                found = true;
0508:                                break;
0509:                            }
0510:                        }
0511:                    }
0512:                    if (!found)
0513:                        throw new FxNotFoundException(
0514:                                "ex.content.xpath.notFound", XPath);
0515:                }
0516:                return group;
0517:            }
0518:
0519:            /**
0520:             * Get the (virtual) root group of this content
0521:             *
0522:             * @return root group
0523:             */
0524:            public FxGroupData getRootGroup() {
0525:                return this .data;
0526:            }
0527:
0528:            /**
0529:             * Set a properties value, needed groups will be created
0530:             *
0531:             * @param XPath FQ XPath
0532:             * @param value value to apply
0533:             * @throws FxNotFoundException         if the requested XPath does not exist
0534:             * @throws FxInvalidParameterException if the request XPath is invalid
0535:             * @throws FxNoAccessException         if the property for this XPath is marked readonly or no access
0536:             * @throws FxCreateException           if missing XPath entries failed to be created
0537:             */
0538:            public void setValue(String XPath, FxValue value)
0539:                    throws FxNotFoundException, FxInvalidParameterException,
0540:                    FxNoAccessException, FxCreateException {
0541:                XPath = XPathElement.stripType(XPath);
0542:                createXPath(XPath);
0543:                List<FxData> prop = getData(XPath);
0544:                if (prop.size() != 1)
0545:                    throw new FxInvalidParameterException("XPATH",
0546:                            "ex.xpath.element.ambiguous.property", XPath);
0547:                if (!(prop.get(0) instanceof  FxPropertyData))
0548:                    throw new FxInvalidParameterException("XPATH",
0549:                            "ex.xpath.element.noProperty", XPath);
0550:                ((FxPropertyData) prop.get(0)).setValue(value);
0551:            }
0552:
0553:            /**
0554:             * Create (if possible and not already exists) the given XPath
0555:             *
0556:             * @param XPath the XPath to create
0557:             * @throws FxInvalidParameterException wrong XPath
0558:             * @throws FxNotFoundException         wrong XPath
0559:             * @throws FxCreateException           on errors creating
0560:             * @throws FxNoAccessException         if req. XPath is not accessible
0561:             */
0562:            private void createXPath(String XPath)
0563:                    throws FxInvalidParameterException, FxNotFoundException,
0564:                    FxCreateException, FxNoAccessException {
0565:                FxEnvironment env = CacheAdmin.getEnvironment();
0566:                if (!env.getType(this .getTypeId()).isXPathValid(XPath, true))
0567:                    throw new FxInvalidParameterException("XPATH",
0568:                            "ex.content.xpath.set.invalid", XPath, env.getType(
0569:                                    getTypeId()).getName());
0570:                XPath = XPath.toUpperCase();
0571:                List<XPathElement> elements = XPathElement.split(XPath);
0572:                FxGroupData currGroup = this .getRootGroup();
0573:                boolean found;
0574:                List<XPathElement> missing = new ArrayList<XPathElement>(20);
0575:                for (int i = 0; i < elements.size(); i++) {
0576:                    found = false;
0577:                    missing.clear();
0578:                    for (int m = 1; m < elements.get(i).getIndex(); m++)
0579:                        missing.add(new XPathElement(
0580:                                elements.get(i).getAlias(), m, true));
0581:                    for (FxData currData : currGroup.getChildren()) {
0582:                        if (currData.getXPathElement().equals(elements.get(i))) {
0583:                            if (currData instanceof  FxPropertyData)
0584:                                return; //last element reached and it exists
0585:                            found = true;
0586:                            currGroup = (FxGroupData) currData;
0587:                            break;
0588:                        } else if (missing.contains(currData.getXPathElement())) {
0589:                            missing.remove(currData.getXPathElement());
0590:                        }
0591:                    }
0592:                    if (found)
0593:                        continue;
0594:                    if (missing.size() > 0) {
0595:                        List<XPathElement> missingPath = new ArrayList<XPathElement>(
0596:                                i + 1);
0597:                        missingPath.addAll(elements.subList(0, i));
0598:                        for (XPathElement currMissing : missing) {
0599:                            missingPath.add(currMissing);
0600:                            //                    System.out.println("Creating missing: "+XPathElement.toXPath(missingPath));
0601:                            currGroup.addEmptyChild(XPathElement
0602:                                    .toXPath(missingPath),
0603:                                    FxData.POSITION_BOTTOM);
0604:                            missingPath.remove(missingPath.size() - 1);
0605:                        }
0606:                    }
0607:                    //create the group or property
0608:                    //            System.out.println("Creating: "+XPathElement.toXPath(elements.subList(0, i+1)));
0609:                    FxData added = currGroup.addEmptyChild(XPathElement
0610:                            .toXPath(elements.subList(0, i + 1)),
0611:                            FxData.POSITION_BOTTOM);
0612:                    if (added instanceof  FxGroupData)
0613:                        currGroup = (FxGroupData) added;
0614:                }
0615:            }
0616:
0617:            /**
0618:             * Get the value of a (property) XPath.
0619:             * This is actually a convenience method that internally calls <code>getPropertyData(XPath).getValuXDEPTHe()</code>
0620:             *
0621:             * @param XPath requested XPath
0622:             * @return FxValue
0623:             * @throws FxNotFoundException         on errors
0624:             * @throws FxInvalidParameterException on errors
0625:             * @see #getPropertyData(String)
0626:             */
0627:            public FxValue getValue(String XPath) throws FxNotFoundException,
0628:                    FxInvalidParameterException {
0629:                return getPropertyData(XPath).getValue();
0630:            }
0631:
0632:            /**
0633:             * Check if a value exists for the given XPath that is not empty
0634:             *
0635:             * @param XPath the XPath to check
0636:             * @return if a value exists for the given XPath that is not empty
0637:             */
0638:            public boolean containsValue(String XPath) {
0639:                try {
0640:                    return !getValue(XPath).isEmpty();
0641:                } catch (Exception e) {
0642:                    return false;
0643:                }
0644:            }
0645:
0646:            /**
0647:             * Check if the given XPath is valid for this content.
0648:             * This is a shortcut to the corresponding type's method!
0649:             *
0650:             * @param XPath         the XPath to check
0651:             * @param checkProperty should the XPath point to a property?
0652:             * @return if the XPath is valid or not
0653:             * @see FxType#isXPathValid(String,boolean)
0654:             */
0655:            public boolean isXPathValid(String XPath, boolean checkProperty) {
0656:                return CacheAdmin.getEnvironment().getType(this .getTypeId())
0657:                        .isXPathValid(XPath, checkProperty);
0658:            }
0659:
0660:            /**
0661:             * Drop all data and create random entries for testing purposes
0662:             *
0663:             * @param maxMultiplicity the maximum multiplicity for groups
0664:             * @return this
0665:             * @throws FxCreateException           on errors
0666:             * @throws FxNotFoundException         on errors
0667:             * @throws FxInvalidParameterException on errors
0668:             */
0669:            public FxContent randomize(int maxMultiplicity)
0670:                    throws FxCreateException, FxNotFoundException,
0671:                    FxInvalidParameterException {
0672:                Random r = new Random();
0673:                FxEnvironment env = CacheAdmin.getEnvironment();
0674:                this .data = env.getType(this .getTypeId()).createRandomData(pk,
0675:                        env, r, maxMultiplicity);
0676:                initSystemProperties();
0677:                return this ;
0678:            }
0679:
0680:            public FxContent randomize() throws FxCreateException,
0681:                    FxNotFoundException, FxInvalidParameterException {
0682:                return randomize(FxMultiplicity.RANDOM_MAX);
0683:            }
0684:
0685:            /**
0686:             * Move data (group or property) within its hierarchy for <code>delta</code>
0687:             * positions up or down depending on the sign of <code>delta</code> without wrapping
0688:             * around if top or bottom position is reached.
0689:             * If delta is Integer.MAX_VALUE the data will always be placed at the bottom,
0690:             * Integer.MIN_VALUE will always place it at the top.
0691:             *
0692:             * @param XPath FQ XPath
0693:             * @param delta relative number of positions to move
0694:             * @throws FxInvalidParameterException for invalid XPath
0695:             * @throws FxNotFoundException         XPath does not exist for this content
0696:             */
0697:            public void move(String XPath, int delta)
0698:                    throws FxInvalidParameterException, FxNotFoundException {
0699:                if (delta == 0 || StringUtils.isEmpty(XPath)
0700:                        || "/".equals(XPath))
0701:                    return; //nothing to do
0702:                List<FxData> mdata = getData(XPath);
0703:                FxGroupData parent = mdata.get(0).getParent();
0704:                XPathElement last = XPathElement.lastElement(XPath);
0705:                parent.moveChild(last, delta);
0706:            }
0707:
0708:            /**
0709:             * Remove the property or group denoted by XPath
0710:             *
0711:             * @param XPath the XPath to remove
0712:             * @throws FxInvalidParameterException if the requested XPath is required and can not be removed
0713:             * @throws FxNotFoundException         if XPath is incorrect
0714:             * @throws FxNoAccessException         if data that is to be removed is readonly or no access
0715:             */
0716:            public void remove(String XPath)
0717:                    throws FxInvalidParameterException, FxNotFoundException,
0718:                    FxNoAccessException {
0719:                FxSharedUtils.checkParameterEmpty(XPath, "XPATH");
0720:                XPath = XPathElement.stripType(XPathElement.toXPathMult(XPath));
0721:                List<FxData> found = getData(XPath);
0722:                FxData data = null;
0723:                if (found.size() == 1) {
0724:                    if (found.get(0).getXPathFull().equals(XPath))
0725:                        data = found.get(0); //property
0726:                }
0727:                if (data == null
0728:                        && found.get(0).getParent() != null
0729:                        && found.get(0).getParent().getXPathFull()
0730:                                .equals(XPath))
0731:                    data = found.get(0).getParent(); //group with single or multiple properties->get parent
0732:                if (data == null || data.getParent() == null)
0733:                    throw new FxNoAccessException(
0734:                            "ex.content.xpath.remove.invalid", XPath);
0735:
0736:                data.getParent().removeChild(data);
0737:            }
0738:
0739:            /**
0740:             * Check if all required properties are present and valid, etc.
0741:             *
0742:             * @throws FxInvalidParameterException if required properties are not present or the content is not valid
0743:             */
0744:            public void checkValidity() throws FxInvalidParameterException {
0745:                _checkGroupValidity(data);
0746:            }
0747:
0748:            /**
0749:             * Recursively check a group and its properties and subgroups if required properties are present
0750:             *
0751:             * @param data FxGroupData to check
0752:             * @throws FxInvalidParameterException if required properties are not present
0753:             */
0754:            private void _checkGroupValidity(FxGroupData data)
0755:                    throws FxInvalidParameterException {
0756:                if (data.getAssignmentMultiplicity().isOptional()
0757:                        && data.isEmpty())
0758:                    return; //if optional groups have required properties or subgroups it still is ok if they are empty!
0759:                for (FxData curr : data.getChildren()) {
0760:                    if (curr instanceof  FxPropertyData) {
0761:                        ((FxPropertyData) curr).checkRequired();
0762:                    } else
0763:                        _checkGroupValidity((FxGroupData) curr);
0764:                }
0765:            }
0766:
0767:            public FxContent initSystemProperties() throws FxNotFoundException,
0768:                    FxInvalidParameterException {
0769:                FxEnvironment env = CacheAdmin.getEnvironment();
0770:                FxType type = env.getType(this .getTypeId());
0771:                FxValue value;
0772:                for (FxPropertyAssignment sp : env
0773:                        .getSystemInternalRootPropertyAssignments()) {
0774:                    if (sp.getAlias().equals("ID"))
0775:                        value = new FxLargeNumber(false, this .getId());
0776:                    else if (sp.getAlias().equals("VERSION"))
0777:                        value = new FxNumber(false, this .getVersion());
0778:                    else if (sp.getAlias().equals("TYPEDEF"))
0779:                        value = new FxLargeNumber(false, this .getTypeId());
0780:                    else if (sp.getAlias().equals("MANDATOR"))
0781:                        value = new FxLargeNumber(false, this .getMandatorId());
0782:                    else if (sp.getAlias().equals("ACL"))
0783:                        value = new FxLargeNumber(false, this .getAclId());
0784:                    else if (sp.getAlias().equals("STEP"))
0785:                        value = new FxLargeNumber(false, this .getStepId());
0786:                    else if (sp.getAlias().equals("MAX_VER"))
0787:                        value = new FxNumber(false, this .getMaxVersion());
0788:                    else if (sp.getAlias().equals("LIVE_VER"))
0789:                        value = new FxNumber(false, this .getLiveVersion());
0790:                    else if (sp.getAlias().equals("ISMAX_VER"))
0791:                        value = new FxBoolean(false, this .isMaxVersion());
0792:                    else if (sp.getAlias().equals("ISLIVE_VER"))
0793:                        value = new FxBoolean(false, this .isLiveVersion());
0794:                    else if (sp.getAlias().equals("ISACTIVE"))
0795:                        value = new FxBoolean(false, this .isActive());
0796:                    else if (sp.getAlias().equals("MAINLANG"))
0797:                        value = new FxLargeNumber(false, this .getMainLanguage());
0798:                    else if (sp.getAlias().equals("CREATED_BY"))
0799:                        value = new FxLargeNumber(false, this 
0800:                                .getLifeCycleInfo().getCreatorId());
0801:                    else if (sp.getAlias().equals("CREATED_AT"))
0802:                        value = new FxDateTime(false, new Date(this 
0803:                                .getLifeCycleInfo().getCreationTime()));
0804:                    else if (sp.getAlias().equals("MODIFIED_BY"))
0805:                        value = new FxLargeNumber(false, this 
0806:                                .getLifeCycleInfo().getModificatorId());
0807:                    else if (sp.getAlias().equals("MODIFIED_AT"))
0808:                        value = new FxDateTime(false, new Date(this 
0809:                                .getLifeCycleInfo().getModificationTime()));
0810:                    else if (type.isRelation()) {
0811:                        if (sp.getAlias().equals("RELSRC"))
0812:                            value = new FxReference(false,
0813:                                    new ReferencedContent(this 
0814:                                            .getRelatedSource()));
0815:                        else if (sp.getAlias().equals("RELDST"))
0816:                            value = new FxReference(false,
0817:                                    new ReferencedContent(this 
0818:                                            .getRelatedDestination()));
0819:                        else if (sp.getAlias().equals("RELSRC_POS"))
0820:                            value = new FxNumber(false, this 
0821:                                    .getRelatedSourcePosition());
0822:                        else if (sp.getAlias().equals("RELDST_POS"))
0823:                            value = new FxNumber(false, this 
0824:                                    .getRelatedDestinationPosition());
0825:                        else
0826:                            value = null;
0827:                    } else
0828:                        value = null;
0829:                    if (value != null) {
0830:                        FxPropertyAssignment this pa = (FxPropertyAssignment) env
0831:                                .getAssignment(type.getName() + "/"
0832:                                        + sp.getAlias());
0833:                        this .data.addProperty(XPathElement.toXPathMult("/"
0834:                                + this pa.getAlias()), this pa, value, this pa
0835:                                .getPosition());
0836:                    }
0837:                }
0838:                return this ;
0839:            }
0840:
0841:            /**
0842:             * Update all system internal properties that provide setters to reflect changes in the FxPropertyData's
0843:             */
0844:            private void updateSystemInternalProperties() {
0845:                try {
0846:                    FxLargeNumber _long = (FxLargeNumber) getValue("/STEP");
0847:                    _long.setValue(stepId);
0848:                    _long = (FxLargeNumber) getValue("/ACL");
0849:                    _long.setValue(aclId);
0850:
0851:                    FxLargeNumber _langlong = (FxLargeNumber) getValue("/MAINLANG");
0852:                    _langlong.setValue(mainLanguage);
0853:
0854:                    FxBoolean _bool = (FxBoolean) getValue("/ISACTIVE");
0855:                    _bool.setValue(isActive());
0856:
0857:                } catch (Exception e) {
0858:                    //bad luck
0859:                }
0860:            }
0861:
0862:            /**
0863:             * Get a list of all property XPaths contained in this content in correct order
0864:             *
0865:             * @return list of all property XPaths contained in this content in correct order
0866:             */
0867:            public List<String> getAllPropertyXPaths() {
0868:                List<String> xpaths = new ArrayList<String>(30);
0869:                _addXPaths(xpaths, this .getRootGroup(), false, null);
0870:                return xpaths;
0871:            }
0872:
0873:            /**
0874:             * Get a list of all XPaths contained in this content in correct order
0875:             *
0876:             * @param groupPostfix String to append to found groups (useful to append "/" to kind of mark those XPaths as group XPaths)
0877:             * @return list of all XPaths contained in this content in correct order
0878:             */
0879:            public List<String> getAllXPaths(String groupPostfix) {
0880:                List<String> xpaths = new ArrayList<String>(30);
0881:                _addXPaths(xpaths, this .getRootGroup(), true, groupPostfix);
0882:                return xpaths;
0883:            }
0884:
0885:            /**
0886:             * Recursively add all xpaths
0887:             *
0888:             * @param xpaths        list of xpaths to build
0889:             * @param group         the current group to process
0890:             * @param includeGroups include groups?
0891:             * @param groupPostfix  String to append to found groups (useful to append "/" to kind of mark those XPaths as group XPaths)
0892:             */
0893:            private void _addXPaths(List<String> xpaths, FxGroupData group,
0894:                    boolean includeGroups, String groupPostfix) {
0895:                for (FxData child : group.getChildren()) {
0896:                    if (child instanceof  FxGroupData) {
0897:                        if (includeGroups)
0898:                            xpaths.add(child.getXPathFull() + groupPostfix);
0899:                        _addXPaths(xpaths, (FxGroupData) child, includeGroups,
0900:                                groupPostfix);
0901:                    } else if (child instanceof  FxPropertyData)
0902:                        xpaths.add(child.getXPathFull());
0903:                }
0904:            }
0905:
0906:            /**
0907:             * Is a preview available that is not a default image?
0908:             *
0909:             * @return preview available
0910:             */
0911:            public boolean isPreviewAvailable() {
0912:                return binaryPreviewId >= 0;
0913:            }
0914:
0915:            /**
0916:             * Id of the binary used for previews
0917:             *
0918:             * @return id of the binary used for previews
0919:             */
0920:            public long getBinaryPreviewId() {
0921:                return binaryPreviewId;
0922:            }
0923:
0924:            /**
0925:             * ACL that is needed to view the preview image
0926:             *
0927:             * @return ACL that is needed to view the preview image
0928:             */
0929:            public long getBinaryPreviewACL() {
0930:                return binaryPreviewACL;
0931:            }
0932:
0933:            /**
0934:             * Set the binary preview to an XPath.
0935:             * Illegal or non-existing values will be ignored!
0936:             *
0937:             * @param XPath the XPath of the requested binary to set as preview
0938:             */
0939:            public void setBinaryPreview(String XPath) {
0940:                try {
0941:                    FxPropertyData data = this .getPropertyData(XPath);
0942:                    if (!(data.getValue() instanceof  FxBinary))
0943:                        return;
0944:                    binaryPreviewId = ((FxBinary) data.getValue())
0945:                            .getDefaultTranslation().getId();
0946:                    binaryPreviewACL = ((FxPropertyAssignment) data
0947:                            .getAssignment()).getACL().getId();
0948:                } catch (Exception e) {
0949:                    //ignore
0950:                }
0951:            }
0952:
0953:            /**
0954:             * Set the binary preview.
0955:             * Illegal or non-existing values will be ignored!
0956:             *
0957:             * @param binaryId if of the requested binary to set as preview
0958:             */
0959:            public void setBinaryPreview(long binaryId) {
0960:                FxPropertyData data = checkPreviewIdExists(binaryId, this 
0961:                        .getRootGroup().getChildren());
0962:                if (data == null)
0963:                    return;
0964:                binaryPreviewId = ((FxBinary) data.getValue())
0965:                        .getDefaultTranslation().getId();
0966:                binaryPreviewACL = ((FxPropertyAssignment) data.getAssignment())
0967:                        .getACL().getId();
0968:            }
0969:
0970:            /**
0971:             * Internal method that tries to find a matching preview image.
0972:             * Searches for images and then regular binaries (preview is then set matching the mime type display).
0973:             * If neither are found the BinaryDescriptor.SYS_UNKNOWN image is used
0974:             *
0975:             * @see com.flexive.shared.value.BinaryDescriptor#SYS_UNKNOWN
0976:             */
0977:            public void resolveBinaryPreview() {
0978:                if (binaryPreviewId >= 0) {
0979:                    //check if the image (still) exists
0980:                    if (checkPreviewIdExists(binaryPreviewId, this 
0981:                            .getRootGroup().getChildren()) == null) {
0982:                        resetBinaryPreview();
0983:                        resolveBinaryPreview();
0984:                    }
0985:                    return;
0986:                }
0987:                FxPropertyData bin = resolveFirstImageData(this .getRootGroup()
0988:                        .getChildren());
0989:                if (bin == null)
0990:                    bin = resolveFirstBinaryData(this .getRootGroup()
0991:                            .getChildren());
0992:                if (bin == null)
0993:                    resetBinaryPreview();
0994:                else {
0995:                    binaryPreviewId = ((FxBinary) bin.getValue())
0996:                            .getDefaultTranslation().getId();
0997:                    binaryPreviewACL = ((FxPropertyAssignment) bin
0998:                            .getAssignment()).getACL().getId();
0999:                }
1000:            }
1001:
1002:            /**
1003:             * Check if an image with the given id exists in this FxContent instance
1004:             *
1005:             * @param binaryPreviewId the binary preview id to search
1006:             * @param groupData       the group data entries to inspect
1007:             * @return <code>true</code> if it exists
1008:             */
1009:            private FxPropertyData checkPreviewIdExists(long binaryPreviewId,
1010:                    List<FxData> groupData) {
1011:                FxPropertyData ret;
1012:                for (FxData data : groupData) {
1013:                    if (data.isGroup()) {
1014:                        ret = checkPreviewIdExists(binaryPreviewId,
1015:                                ((FxGroupData) data).getChildren());
1016:                        if (ret != null)
1017:                            return ret;
1018:                    }
1019:                    if (data.isProperty()
1020:                            && data instanceof  FxPropertyData
1021:                            && ((FxPropertyData) data).getValue() instanceof  FxBinary) {
1022:                        FxBinary bin = (FxBinary) ((FxPropertyData) data)
1023:                                .getValue();
1024:                        if (!bin.isEmpty()
1025:                                && bin.getDefaultTranslation().getId() == binaryPreviewId)
1026:                            return (FxPropertyData) data;
1027:                    }
1028:                }
1029:                return null;
1030:            }
1031:
1032:            /**
1033:             * Find the first available binary data value and return it
1034:             *
1035:             * @param groupData the group data entries to inspect
1036:             * @return the first available binary data value or <code>null</code>
1037:             */
1038:            private FxPropertyData resolveFirstBinaryData(List<FxData> groupData) {
1039:                FxPropertyData ret = null;
1040:                for (FxData data : groupData) {
1041:                    if (data.isGroup())
1042:                        ret = resolveFirstBinaryData(((FxGroupData) data)
1043:                                .getChildren());
1044:                    if (ret != null)
1045:                        return ret;
1046:                    if (data.isProperty()
1047:                            && data instanceof  FxPropertyData
1048:                            && ((FxPropertyData) data).getValue() instanceof  FxBinary) {
1049:                        FxBinary bin = (FxBinary) ((FxPropertyData) data)
1050:                                .getValue();
1051:                        if (!bin.isEmpty())
1052:                            return (FxPropertyData) data;
1053:                    }
1054:                }
1055:                return ret;
1056:            }
1057:
1058:            /**
1059:             * Find the first available image data value and return it
1060:             *
1061:             * @param groupData the group data entries to inspect
1062:             * @return the first available image data value or <code>null</code>
1063:             */
1064:            private FxPropertyData resolveFirstImageData(List<FxData> groupData) {
1065:                FxPropertyData ret = null;
1066:                for (FxData data : groupData) {
1067:                    if (data.isGroup())
1068:                        ret = resolveFirstImageData(((FxGroupData) data)
1069:                                .getChildren());
1070:                    if (ret != null)
1071:                        return ret;
1072:                    if (data.isProperty()
1073:                            && data instanceof  FxPropertyData
1074:                            && ((FxPropertyData) data).getValue() instanceof  FxBinary) {
1075:                        FxBinary bin = (FxBinary) ((FxPropertyData) data)
1076:                                .getValue();
1077:                        if (!bin.isEmpty()
1078:                                && bin.getDefaultTranslation().isImage())
1079:                            return (FxPropertyData) data;
1080:                    }
1081:                }
1082:                return ret;
1083:            }
1084:
1085:            /**
1086:             * Reset the preview image to show the default BinaryDescriptor.SYS_UNKNOWN image.
1087:             *
1088:             * @see BinaryDescriptor#SYS_UNKNOWN
1089:             */
1090:            public void resetBinaryPreview() {
1091:                this .binaryPreviewId = BinaryDescriptor.SYS_UNKNOWN;
1092:                this .binaryPreviewACL = 1;
1093:            }
1094:
1095:            /**
1096:             * Create an independent copy of this FxContent
1097:             *
1098:             * @return a copy of this FxContent
1099:             */
1100:            public FxContent copy() {
1101:                FxContent clone;
1102:                clone = new FxContent(pk, typeId, relation, mandatorId, aclId,
1103:                        stepId, maxVersion, liveVersion, active, mainLanguage,
1104:                        relatedSource, relatedDestination,
1105:                        relatedSourcePosition, relatedDestinationPosition,
1106:                        lifeCycleInfo, data.copy(null), binaryPreviewId,
1107:                        binaryPreviewACL);
1108:                return clone;
1109:            }
1110:
1111:            /**
1112:             * Load all FxContent instances from properties of type FxReference
1113:             *
1114:             * @param ce ContentEngine
1115:             * @throws FxApplicationException on errors
1116:             */
1117:            public void loadReferences(ContentEngine ce)
1118:                    throws FxApplicationException {
1119:                List<FxReference> references = getRootGroup().getReferences(
1120:                        true);
1121:                //        int refcount = 0;
1122:                //        long time = System.currentTimeMillis();
1123:                for (FxReference ref : references) {
1124:                    if (ref.isEmpty() || !ref.isValid())
1125:                        continue;
1126:                    if (ref.isMultiLanguage()) {
1127:                        for (long lang : ref.getTranslatedLanguages()) {
1128:                            ReferencedContent r = ref.getTranslation(lang);
1129:                            if (!r.hasContent() && r.isAccessGranted()) {
1130:                                r.setContent(ce.load(r));
1131:                                //                        refcount++;
1132:                            }
1133:                        }
1134:                    } else {
1135:                        if (!ref.getDefaultTranslation().hasContent()
1136:                                && ref.getDefaultTranslation()
1137:                                        .isAccessGranted())
1138:                            ref.getDefaultTranslation().setContent(
1139:                                    ce.load(ref.getDefaultTranslation()));
1140:                        //                refcount++;
1141:                    }
1142:                }
1143:                //        System.out.println("=> Loading " + refcount + " references took " + (System.currentTimeMillis() - time) + "[ms]");
1144:            }
1145:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.