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.exceptions.FxInvalidParameterException;
036: import com.flexive.shared.security.ACL;
037: import com.flexive.shared.value.FxString;
038: import org.apache.commons.lang.StringUtils;
039:
040: import java.util.List;
041:
042: /**
043: * FxProperty used for structure editing
044: *
045: * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
046: */
047: public class FxPropertyEdit extends FxProperty {
048:
049: private static final long serialVersionUID = 2628385928536891500L;
050: private boolean isNew;
051: private boolean autoUniquePropertyName = false;
052: private int defaultMultiplicity = 1;
053:
054: /**
055: * Make an editable instance of an existing property
056: *
057: * @param prop original property
058: */
059: public FxPropertyEdit(FxProperty prop) {
060: super (prop.getId(), prop.getName(), prop.getLabel().copy(),
061: prop.getHint().copy(), prop.isSystemInternal(), prop
062: .mayOverrideBaseMultiplicity(),
063: new FxMultiplicity(prop.getMultiplicity()), prop
064: .mayOverrideACL(), new ACL(prop.getACL()), prop
065: .getDataType(), prop.getDefaultValue().copy(),
066: prop.isFulltextIndexed(), prop.getReferencedType(),
067: prop.getReferencedList(), prop.getUniqueMode(),
068: FxStructureOption.cloneOptions(prop.options));
069: isNew = false;
070: }
071:
072: /**
073: * Create a clone of an existing property with a new name
074: *
075: * @param base property to clone
076: * @param newName new name to assign
077: * @param autoUniquePropertyName if the property name already exists, try to find a unique one (by appending "_([counter])").
078: * Useful if creating property assignments and the used property name is not important
079: * @return FxPropertyEdit
080: * @throws FxInvalidParameterException on errors
081: */
082: public static FxPropertyEdit createNew(FxProperty base,
083: String newName, boolean autoUniquePropertyName)
084: throws FxInvalidParameterException {
085: FxPropertyEdit ret = new FxPropertyEdit(base).setName(newName)
086: .setAutoUniquePropertyName(autoUniquePropertyName);
087: ret.isNew = true;
088: return ret;
089: }
090:
091: /**
092: * Create a clone of an existing property with a new name
093: *
094: * @param base property to clone
095: * @param newName new name to assign (has to be mandatorwide unique!)
096: * @return FxPropertyEdit
097: */
098: public static FxPropertyEdit createNew(FxProperty base,
099: String newName) {
100: FxPropertyEdit ret = new FxPropertyEdit(base).setName(newName);
101: ret.isNew = true;
102: return ret;
103: }
104:
105: /**
106: * Constructor
107: *
108: * @param name (mandator wide unique) name of the property
109: * @param description description
110: * @param hint hint message
111: * @param overrideBaseMultiplicity are assignments allowed to override this properties multiplicity?
112: * @param multiplicity multiplicity
113: * @param overrideACL are assignments allowed to override this properties ACL?
114: * @param ACL ACL
115: * @param dataType FxDataType
116: * @param defaultValue default value to assign
117: * @param fulltextIndexed should vlues of this property be fulltext indexed?
118: * @param referencedType if dataType is reference this is the referenced type
119: * @param referencedList if dataType is (multi) select list this is the referenced list
120: * @param options this properties options
121: */
122: private FxPropertyEdit(String name, FxString description,
123: FxString hint, boolean overrideBaseMultiplicity,
124: FxMultiplicity multiplicity, boolean overrideACL, ACL ACL,
125: FxDataType dataType, FxString defaultValue,
126: boolean fulltextIndexed, FxType referencedType,
127: FxSelectList referencedList, List<FxStructureOption> options) {
128: super (-1, name, description, hint, false,
129: overrideBaseMultiplicity, multiplicity, overrideACL,
130: ACL, dataType, defaultValue, fulltextIndexed,
131: referencedType, referencedList, UniqueMode.None,
132: options);
133: setName(name);
134: setSearchable(true); //default is searchable
135: this .isNew = true;
136: }
137:
138: /**
139: * Create a new FxPropertyEdit instance
140: *
141: * @param name (mandator wide unique) name of the property
142: * @param description description
143: * @param hint hint message
144: * @param overrideBaseMultiplicity are assignments allowed to override this properties multiplicity?
145: * @param multiplicity multiplicity
146: * @param overrideACL are assignments allowed to override this properties ACL?
147: * @param acl ACL
148: * @param dataType FxDataType
149: * @param defaultValue default value to assign
150: * @param fulltextIndexed should values of this property be fulltext indexed?
151: * @param referencedType if dataType is reference this is the referenced type
152: * @param referencedList if dataType is (multi) select list this is the referenced list
153: * @param options this properties options
154: * @return FxPropertyEdit instance
155: */
156: public static FxPropertyEdit createNew(String name,
157: FxString description, FxString hint,
158: boolean overrideBaseMultiplicity,
159: FxMultiplicity multiplicity, boolean overrideACL, ACL acl,
160: FxDataType dataType, FxString defaultValue,
161: boolean fulltextIndexed, FxType referencedType,
162: FxSelectList referencedList, List<FxStructureOption> options) {
163: return new FxPropertyEdit(name, description, hint,
164: overrideBaseMultiplicity, multiplicity, overrideACL,
165: acl, dataType, defaultValue, fulltextIndexed,
166: referencedType, referencedList, options);
167: }
168:
169: /**
170: * Create a new FxPropertyEdit instance - simplified with many defaults (everything set to true except useHTMLEditor)
171: *
172: * @param name (mandator wide unique) name of the property
173: * @param description description
174: * @param hint hint message
175: * @param multiplicity multiplicity
176: * @param acl ACL
177: * @param dataType FxDataType
178: * @return FxPropertyEdit instance
179: */
180: public static FxPropertyEdit createNew(String name,
181: FxString description, FxString hint,
182: FxMultiplicity multiplicity, ACL acl, FxDataType dataType) {
183: return new FxPropertyEdit(name, description, hint, true,
184: multiplicity, true, acl, dataType, new FxString(""),
185: true, null, null, FxStructureOption
186: .getEmptyOptionList(5));
187: }
188:
189: /**
190: * Is this a new property
191: *
192: * @return if this is a new property
193: */
194: public boolean isNew() {
195: return isNew;
196: }
197:
198: /**
199: * If creating a new property and the property name (not assignment! xalias will remain!) is taken probe for and
200: * use a unique property name?
201: *
202: * @return probe for unique property name if a property with the requested xalias already exist?
203: */
204: public boolean isAutoUniquePropertyName() {
205: return autoUniquePropertyName;
206: }
207:
208: /**
209: * If creating a new property and the property name (not assignment! xalias will remain!) is taken probe for and
210: * use a unique property name?
211: *
212: * @param autoUniquePropertyName probe for a unique propery name if a property with the requested xalias already exist?
213: * @return the property itself, useful for chained calls
214: */
215: public FxPropertyEdit setAutoUniquePropertyName(
216: boolean autoUniquePropertyName) {
217: this .autoUniquePropertyName = autoUniquePropertyName;
218: return this ;
219: }
220:
221: /**
222: * Set the properties name (has to be unique!)
223: *
224: * @param name (unique) name of the property
225: * @return the property itself, useful for chained calls
226: * @throws com.flexive.shared.exceptions.FxRuntimeException
227: * if the name is empty (uniqueness will be checked during save operation)
228: */
229: public FxPropertyEdit setName(String name) {
230: if (StringUtils.isEmpty(name))
231: throw new FxInvalidParameterException("NAME",
232: "ex.general.parameter.empty", "name")
233: .asRuntimeException();
234: name = name.trim().toUpperCase();
235: this .name = name;
236: return this ;
237: }
238:
239: /**
240: * Set the label
241: *
242: * @param label the label
243: * @return the property itself, useful for chained calls
244: */
245: public FxPropertyEdit setLabel(FxString label) {
246: this .label = label;
247: return this ;
248: }
249:
250: /**
251: * Set the hint message
252: *
253: * @param hint hint message
254: * @return the property itself, useful for chained calls
255: */
256: public FxPropertyEdit setHint(FxString hint) {
257: this .hint = hint;
258: return this ;
259: }
260:
261: /**
262: * Set the multiplicity
263: *
264: * @param multiplicity multiplicity
265: * @return the property itself, useful for chained calls
266: */
267: public FxPropertyEdit setMultiplicity(FxMultiplicity multiplicity) {
268: this .multiplicity = multiplicity;
269: return this ;
270: }
271:
272: /**
273: * Set if assignments are allowed to override this properties multiplicity?
274: *
275: * @param overrideMultiplicity are assignments allowed to override this properties multiplicity?
276: * @return the property itself, useful for chained calls
277: */
278: public FxPropertyEdit setOverrideMultiplicity(
279: boolean overrideMultiplicity) {
280: this .overrideMultiplicity = overrideMultiplicity;
281: return this ;
282: }
283:
284: /**
285: * Set the ACL
286: *
287: * @param acl ACL
288: * @return the property itself, useful for chained calls
289: */
290: public FxPropertyEdit setACL(ACL acl) {
291: this .ACL = acl;
292: return this ;
293: }
294:
295: /**
296: * Set if assignments of this propery are allowed to override this properties ACL?
297: *
298: * @param overrideACL are assignments allowed to override this properties ACL?
299: * @return the property itself, useful for chained calls
300: */
301: public FxPropertyEdit setOverrideACL(boolean overrideACL) {
302: this .overrideACL = overrideACL;
303: return this ;
304: }
305:
306: /**
307: * Set the data type
308: *
309: * @param dataType data type
310: * @return the property itself, useful for chained calls
311: */
312: public FxPropertyEdit setDataType(FxDataType dataType) {
313: this .dataType = dataType;
314: return this ;
315: }
316:
317: /**
318: * Set multilinguality
319: *
320: * @param multiLang are values of this property multilingual?
321: * @return the property itself, useful for chained calls
322: */
323: public FxPropertyEdit setMultiLang(boolean multiLang) {
324: FxStructureOption.setOption(options,
325: FxStructureOption.OPTION_MULTILANG,
326: mayOverrideMultiLang(), multiLang);
327: return this ;
328: }
329:
330: /**
331: * Set if assignments are allowed to override this properties multilanguage setting?
332: *
333: * @param overrideMultiLang are assignments allowed to override this properties multilanguage setting?
334: * @return the property itself, useful for chained calls
335: */
336: public FxPropertyEdit setOverrideMultiLang(boolean overrideMultiLang) {
337: FxStructureOption.setOption(options,
338: FxStructureOption.OPTION_MULTILANG, overrideMultiLang,
339: isMultiLang());
340: return this ;
341: }
342:
343: /**
344: * Set multiline display ability
345: *
346: * @param multiLine render property in multiple lines?
347: * @return the property itself, useful for chained calls
348: */
349: public FxPropertyEdit setMultiLine(boolean multiLine) {
350: FxStructureOption.setOption(options,
351: FxStructureOption.OPTION_MULTILINE,
352: mayOverrideMultiLine(), multiLine);
353: return this ;
354: }
355:
356: /**
357: * Set if assignments are allowed to override this properties multiline setting?
358: *
359: * @param overrideMultiLine are assignments allowed to override this properties multiline setting?
360: * @return the property itself, useful for chained calls
361: */
362: public FxPropertyEdit setOverrideMultiLine(boolean overrideMultiLine) {
363: FxStructureOption.setOption(options,
364: FxStructureOption.OPTION_MULTILINE, overrideMultiLine,
365: isMultiLine());
366: return this ;
367: }
368:
369: /**
370: * Set if this property be used in the visual query editor (UI hint)
371: *
372: * @param searchable property can be used in the visual query editor
373: * @return the property itself, useful for chained calls
374: */
375: public FxPropertyEdit setSearchable(boolean searchable) {
376: FxStructureOption.setOption(options,
377: FxStructureOption.OPTION_SEARCHABLE,
378: mayOverrideSearchable(), searchable);
379: return this ;
380: }
381:
382: /**
383: * Set if assignments are allowed to override this properties multilanguage setting?
384: *
385: * @param overrideSearchable are assignments allowed to override this properties multilanguage setting?
386: * @return the property itself, useful for chained calls
387: */
388: public FxPropertyEdit setOverrideSearchable(
389: boolean overrideSearchable) {
390: FxStructureOption.setOption(options,
391: FxStructureOption.OPTION_SEARCHABLE,
392: overrideSearchable, isSearchable());
393: return this ;
394: }
395:
396: /**
397: * Set overview appearance setting
398: *
399: * @param inOverview overview appearance setting
400: * @return the property itself, useful for chained calls
401: */
402: public FxPropertyEdit setInOverview(boolean inOverview) {
403: FxStructureOption.setOption(options,
404: FxStructureOption.OPTION_SHOW_OVERVIEW,
405: mayOverrideInOverview(), inOverview);
406: return this ;
407: }
408:
409: /**
410: * Set if assignments are allowed to override this properties appearance in overviews?
411: *
412: * @param overrideOverview are assignments allowed to override this properties appearance in overviews?
413: * @return the property itself, useful for chained calls
414: */
415: public FxPropertyEdit setOverrideOverview(boolean overrideOverview) {
416: FxStructureOption.setOption(options,
417: FxStructureOption.OPTION_SHOW_OVERVIEW,
418: overrideOverview, isInOverview());
419: return this ;
420: }
421:
422: /**
423: * Set if to use an HTML editor to edit values of this property?
424: *
425: * @param useHTMLEditor use HTML editor to edit values of this property?
426: * @return the property itself, useful for chained calls
427: */
428: public FxPropertyEdit setUseHTMLEditor(boolean useHTMLEditor) {
429: FxStructureOption.setOption(options,
430: FxStructureOption.OPTION_HTML_EDITOR,
431: mayOverrideInOverview(), useHTMLEditor);
432: return this ;
433: }
434:
435: /**
436: * Set if assignments are allowed to override this properties use of HTML editor setting?
437: *
438: * @param overrideHTMLEditor are assignments allowed to override this properties use of HTML editor setting?
439: * @return the property itself, useful for chained calls
440: */
441: public FxPropertyEdit setOverrideHTMLEditor(
442: boolean overrideHTMLEditor) {
443: FxStructureOption.setOption(options,
444: FxStructureOption.OPTION_HTML_EDITOR,
445: overrideHTMLEditor, isUseHTMLEditor());
446: return this ;
447: }
448:
449: /**
450: * Set an option
451: *
452: * @param key option key
453: * @param overrideable is the option overrideable from assignments?
454: * @param value value of the option
455: * @return the property itself, useful for chained calls
456: */
457: public FxPropertyEdit setOption(String key, boolean overrideable,
458: String value) {
459: FxStructureOption.setOption(options, key, overrideable, value);
460: return this ;
461: }
462:
463: /**
464: * Set a boolean option
465: *
466: * @param key option key
467: * @param overrideable is the option overrideable from assignments?
468: * @param value value of the option
469: * @return the property itself, useful for chained calls
470: */
471: public FxPropertyEdit setOption(String key, boolean overrideable,
472: boolean value) {
473: FxStructureOption.setOption(options, key, overrideable, value);
474: return this ;
475: }
476:
477: /**
478: * Change the overrideable status of an option, will only have effect if the option exists!
479: *
480: * @param key option key
481: * @param overrideable overrideable status
482: * @return the property itself, useful for chained calls
483: */
484: public FxPropertyEdit setOptionOverrideable(String key,
485: boolean overrideable) {
486: FxStructureOption opt = getOption(key);
487: if (opt.isSet())
488: opt.overrideable = overrideable;
489: return this ;
490: }
491:
492: /**
493: * Clear an option entry
494: *
495: * @param key option name
496: */
497: public void clearOption(String key) {
498: FxStructureOption.clearOption(options, key);
499: }
500:
501: /**
502: * Set if values of this property should be fulltext indexed?
503: *
504: * @param fulltextIndexed should values of this property be fulltext indexed?
505: * @return the property itself, useful for chained calls
506: */
507: public FxPropertyEdit setFulltextIndexed(boolean fulltextIndexed) {
508: this .fulltextIndexed = fulltextIndexed;
509: return this ;
510: }
511:
512: /**
513: * Set the uniqueness mode of this property
514: *
515: * @param uniqueMode uniqueness mode
516: * @return the property itself, useful for chained calls
517: */
518: public FxPropertyEdit setUniqueMode(UniqueMode uniqueMode) {
519: this .uniqueMode = uniqueMode;
520: return this ;
521: }
522:
523: /**
524: * If this propery is a reference to a FxType, set the referenced type
525: *
526: * @param referencedType if dataType is reference this is the referenced type
527: * @return the property itself, useful for chained calls
528: */
529: public FxPropertyEdit setReferencedType(FxType referencedType) {
530: this .referencedType = referencedType;
531: return this ;
532: }
533:
534: /**
535: * If this propery is a (multi) select list, set the referenced list
536: *
537: * @param referencedList if dataType is a (multi) select list, set the referenced list
538: * @return the property itself, useful for chained calls
539: */
540: public FxPropertyEdit setReferencedList(FxSelectList referencedList) {
541: this .referencedList = referencedList;
542: return this ;
543: }
544:
545: /**
546: * Perform some consistency checks, called internally!
547: */
548: public void checkConsistency() {
549: switch (this .getDataType()) {
550: case Reference:
551: //check if a reference is set
552: if (!hasReferencedType())
553: throw new FxInvalidParameterException("referencedType",
554: "ex.structure.property.missing.type", this
555: .getName()).asRuntimeException();
556: break;
557: case SelectOne:
558: case SelectMany:
559: //check if select list is set
560: if (!hasReferencedList())
561: throw new FxInvalidParameterException("referencedList",
562: "ex.structure.property.missing.list", this
563: .getName()).asRuntimeException();
564: break;
565: default:
566: break; //no checks
567: }
568: }
569:
570: /**
571: * Get a (unmodifiable) list of all options set for this property
572: *
573: * @return (unmodifiable) list of all options set for this property
574: */
575: public List<FxStructureOption> getOptions() {
576: return FxStructureOption.getUnmodifieableOptions(options);
577: }
578:
579: /**
580: * <b>This value set will only be used when creating a new property and will be set for the created assignment!</b>
581: * Set the default multiplicity (used i.e. in user interfaces editors and determines the amount of values that will
582: * be initialized when creating an empty element).
583: * <p/>
584: * If the set value is < min or > max multiplicity of this assignment it will
585: * be auto adjusted to the next valid value without throwing an exception
586: *
587: * @param defaultMultiplicity the default multiplicity
588: * @return this
589: */
590: public FxPropertyEdit setAssignmentDefaultMultiplicity(
591: int defaultMultiplicity) {
592: this .defaultMultiplicity = defaultMultiplicity;
593: return this ;
594: }
595:
596: /**
597: * Get the created assignments default multiplicity
598: *
599: * @return default multiplicity
600: */
601: public int getAssignmentDefaultMultiplicity() {
602: return defaultMultiplicity;
603: }
604: }
|