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.structure;
034:
035: import com.flexive.shared.FxLanguage;
036: import com.flexive.shared.XPathElement;
037: import com.flexive.shared.content.FxData;
038: import com.flexive.shared.content.FxGroupData;
039: import com.flexive.shared.content.FxPropertyData;
040: import com.flexive.shared.exceptions.FxCreateException;
041: import com.flexive.shared.exceptions.FxInvalidParameterException;
042: import com.flexive.shared.security.ACL;
043: import com.flexive.shared.value.FxString;
044: import com.flexive.shared.value.FxValue;
045:
046: import java.io.Serializable;
047: import java.util.List;
048: import java.util.Random;
049:
050: /**
051: * Assignment of a property to a type or group
052: *
053: * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
054: */
055: public class FxPropertyAssignment extends FxAssignment implements
056: Serializable {
057: private static final long serialVersionUID = -4825188658392104371L;
058:
059: /**
060: * The property assigned
061: */
062: protected FxProperty property;
063:
064: /**
065: * Overridden ACL (if the embedded property permits)
066: */
067: protected ACL ACL;
068:
069: protected FxValue defaultValue;
070:
071: protected long defaultLang;
072:
073: /**
074: * Constructor
075: *
076: * @param assignmentId internal id of this assignment
077: * @param enabled is this assignment enabled?
078: * @param assignedType the FxType this assignment belongs to
079: * @param alias an optional alias, if <code>null</code> the original name will be used
080: * @param xpath XPath relative to the assigned FxType
081: * @param position position within the same XPath hierarchy
082: * @param multiplicity multiplicity (will only be used if the embedded property allows overriding)
083: * @param defaultMultiplicity default multiplicity
084: * @param parentGroupAssignment (optional) parent FxGroupAssignment this property assignment belongs to
085: * @param baseAssignment base assignment (if derived the parent, if not the root assignment, if its a root assignment FxAssignment.ROOT_BASE)
086: * @param label (optional) label
087: * @param hint (optional) hint
088: * @param defaultValue (optional) default value
089: * @param property the assigned property
090: * @param ACL the embedded property's ACL (will only be used if the embedded property allows overriding)
091: * @param defaultLang default language if multilingual (if 0==SYSTEM then not set)
092: * @param options options
093: */
094: public FxPropertyAssignment(long assignmentId, boolean enabled,
095: FxType assignedType, String alias, String xpath,
096: int position, FxMultiplicity multiplicity,
097: int defaultMultiplicity,
098: FxGroupAssignment parentGroupAssignment,
099: long baseAssignment, FxString label, FxString hint,
100: FxValue defaultValue, FxProperty property, ACL ACL,
101: long defaultLang, List<FxStructureOption> options) {
102: super (assignmentId, enabled, assignedType, alias, xpath,
103: position, multiplicity, defaultMultiplicity,
104: parentGroupAssignment, baseAssignment, label, hint,
105: options);
106: this .defaultValue = defaultValue;
107: this .property = property;
108: if (alias == null || alias.trim().length() == 0)
109: this .alias = property.getName();
110: this .defaultLang = defaultLang;
111: this .ACL = ACL;
112: }
113:
114: /**
115: * Get the property this assignment relates to
116: *
117: * @return property this assignment relates to
118: */
119: public FxProperty getProperty() {
120: return property;
121: }
122:
123: /**
124: * Get the ACL of the embedded property. If the property does not allow overriding
125: * ACL the original property ACL will be returned
126: *
127: * @return the ACL
128: */
129: public ACL getACL() {
130: return (getProperty().mayOverrideACL() && this .ACL != null ? this .ACL
131: : getProperty().getACL());
132: }
133:
134: /**
135: * Get the multiplicity of this assignment.
136: * Depending on if the assigned element allows overriding of its base multiplicity the base
137: * elements multiplicity is returned or the multiplicity of the assignment
138: *
139: * @return multiplicity of this assignment
140: */
141: @Override
142: public FxMultiplicity getMultiplicity() {
143: return (getProperty().mayOverrideBaseMultiplicity()
144: && this .multiplicity != null ? this .multiplicity
145: : getProperty().getMultiplicity());
146: }
147:
148: /**
149: * {@inheritDoc}
150: */
151: @Override
152: public FxStructureOption getOption(String key) {
153: FxStructureOption pOpt = property.getOption(key);
154: if (!pOpt.isSet())
155: return super .getOption(key);
156: if (!pOpt.isOverrideable())
157: return pOpt;
158: if (super .hasOption(key))
159: return super .getOption(key);
160: return pOpt;
161: }
162:
163: /**
164: * {@inheritDoc}
165: */
166: @Override
167: public boolean hasOption(String key) {
168: return super .hasOption(key) || property.hasOption(key);
169: }
170:
171: public boolean isMultiLang() {
172: return getOption(FxStructureOption.OPTION_MULTILANG)
173: .isValueTrue();
174: }
175:
176: public boolean isSearchable() {
177: return getOption(FxStructureOption.OPTION_SEARCHABLE)
178: .isValueTrue();
179: }
180:
181: public boolean isInOverview() {
182: return getOption(FxStructureOption.OPTION_SHOW_OVERVIEW)
183: .isValueTrue();
184: }
185:
186: public boolean isUseHTMLEditor() {
187: return getOption(FxStructureOption.OPTION_HTML_EDITOR)
188: .isValueTrue();
189: }
190:
191: /**
192: * Show as multiple lines in editors?
193: *
194: * @return if this property appears in multiple lines
195: */
196: public boolean isMultiLine() {
197: return getOption(FxStructureOption.OPTION_MULTILINE)
198: .isValueTrue();
199: }
200:
201: /**
202: * Get the default value for this assignment
203: *
204: * @return FxValue
205: */
206: public FxValue getDefaultValue() {
207: return defaultValue;
208: }
209:
210: /**
211: * Get an empty FxValue object for this assignment
212: *
213: * @return empty FxValue object
214: */
215: public FxValue getEmptyValue() {
216: if (hasDefaultLanguage())
217: return this .getProperty().getEmptyValue(this .isMultiLang(),
218: this .getDefaultLanguage()).setXPath(getXPath());
219: else
220: return this .getProperty().getEmptyValue(this .isMultiLang())
221: .setXPath(getXPath());
222: }
223:
224: /**
225: * {@inheritDoc}
226: */
227: @Override
228: public FxData createEmptyData(FxGroupData parent, int index)
229: throws FxCreateException {
230: String XPathFull = (this .hasParentGroupAssignment()
231: && parent != null ? parent.getXPathFull() : "")
232: + "/" + this .getAlias();
233: String XPath = (this .hasParentGroupAssignment()
234: && parent != null ? parent.getXPath() : "")
235: + "/" + this .getAlias();
236: try {
237: if (!this .getMultiplicity().isValid(index))
238: throw new FxCreateException(
239: "ex.content.xpath.index.invalid", index, this
240: .getMultiplicity(), this .getXPath())
241: .setAffectedXPath(parent != null ? parent
242: .getXPathFull() : this .getXPath());
243: //TODO: permission checks missing!
244: return new FxPropertyData(parent == null ? "" : parent
245: .getXPathPrefix(), this .getAlias(), index, XPath,
246: XPathElement.toXPathMult(XPathFull), XPathElement
247: .getIndices(XPathFull), this .getId(), this
248: .getProperty().getId(), this
249: .getMultiplicity(), this .getPosition(),
250: parent, this .getEmptyValue(), this
251: .isSystemInternal());
252: } catch (FxInvalidParameterException e) {
253: throw new FxCreateException(e);
254: }
255: }
256:
257: /**
258: * {@inheritDoc}
259: */
260: @Override
261: public FxData createRandomData(Random rnd, FxEnvironment env,
262: FxGroupData parent, int index, int maxMultiplicity)
263: throws FxCreateException {
264: String XPathFull = (this .hasParentGroupAssignment()
265: && parent != null ? parent.getXPathFull() : "")
266: + "/" + this .getAlias();
267: String XPath = (this .hasParentGroupAssignment()
268: && parent != null ? parent.getXPath() : "")
269: + "/" + this .getAlias();
270: try {
271: if (!this .getMultiplicity().isValid(index))
272: throw new FxCreateException(
273: "ex.content.xpath.index.invalid", index, this
274: .getMultiplicity(), this .getXPath())
275: .setAffectedXPath(parent != null ? parent
276: .getXPathFull() : this .getXPath());
277: return new FxPropertyData(parent == null ? "" : parent
278: .getXPathPrefix(), this .getAlias(), index, XPath,
279: XPathElement.toXPathMult(XPathFull), XPathElement
280: .getIndices(XPathFull), this .getId(), this
281: .getProperty().getId(), this
282: .getMultiplicity(), this .getPosition(),
283: parent, this .getProperty().getDataType()
284: .getRandomValue(rnd, this ), this
285: .isSystemInternal());
286: } catch (FxInvalidParameterException e) {
287: throw new FxCreateException(e);
288: }
289: }
290:
291: /**
292: * {@inheritDoc}
293: */
294: @Override
295: public boolean isValid(Object value) {
296: // TODO: add assignment-based validation here
297: return property.getDataType().isValid(value);
298: }
299:
300: /**
301: * Is a default language defined for this property assignment?
302: *
303: * @return if a default language is defined for this property assignment
304: */
305: public boolean hasDefaultLanguage() {
306: return defaultLang != FxLanguage.SYSTEM_ID && isMultiLang();
307: }
308:
309: /**
310: * Get the default language for this property assignment (if set)
311: *
312: * @return default language for this property assignment (if set)
313: */
314: public long getDefaultLanguage() {
315: return defaultLang;
316: }
317:
318: /**
319: * Get this FxPropertyAssignment as editable
320: *
321: * @return FxPropertyAssignmentEdit
322: */
323: public FxPropertyAssignmentEdit asEditable() {
324: return new FxPropertyAssignmentEdit(this);
325: }
326:
327: }
|