One of the core tasks of [fleXive] is to store and query data. Like in relational databases or well-formed XML files, data needs to match a predefined structure. When [fleXive] was designed the requirements were as follows:
A good analogy to explain how structures in [fleXive] are organised are classes and object instances: a
class in
an object oriented programming language describes which attributes (in [fleXive] called
properties) are available.
If an attribute itself acts like a container for other attributes we call it a
group.
We call the class analogon
Type
(implemented in the class
FxType), attributes
property
(implemented in
FxProperty) and a collection of attributes
Group
(implemented in
FxGroup).
To enable reuse of properties and groups these entities are independent of types and need to be assigned to types (and respectively groups). The benefit of this system - although it might sound a bit confusing at first glance - is that different types and assignments can share the same property which can be a big advantage for query operations [1] .
A special extension to types are relations (implemented in
FxType, mode:
Relation) which mimics the behaviour of attributed n:m relations known from SQL.
Structure elements can be addressed using XPath-like expressions as shown in the section called “Content Engine”.
| Element | Class | Description |
|---|---|---|
| Type |
FxType
|
A type, identified by its name, defines behaviour (what kind of permissions may be applied, storage model or language mode is to be used, etc.) and structure (properties and groups are assigned to types). |
| Relation |
FxType
(mode:Relation)
|
A relation is basically a type that relates (or links) two other types together. A good analogy is an attributed relation known from SQL. It is possible to define how many times a specific instance may be used as a relation source or destination and which types may be related. |
| Property |
FxProperty
|
A property defines a name and a datatype (and some options). Thats all there is to it! It can only exist (and is of relevance) if it is assigned to a type or group. The purpose of keeping properties and their assignments separate is the ability to share them and query across multiple types with a single property. |
| Group |
FxGroup
|
A group serves as a container for properties and combines them to an entity. Groups - just
like properties can not exist without assignments to types (
FxGroupAssignment). The purpose for their existance is like for properties: the
ability to share and query across multiple types.
|
| Assignment |
FxAssignment
|
An assignment is the correlation of groups and properties to types. A group or property can only be used in instances if it is connected to a group assignment or a type. |
| Property assignment |
FxPropertyAssignment
|
The assignment of a property to a group assignment or a type. If the property that is being assigned permits, settings like the access control list or options may be overridden. |
| Group assignment |
FxGroupAssignment
|
The assignment of a group to a group assignment or a type. If the group that is being assigned permits, settings like the access control list or options may be overridden. |
Following the convention on how to update or create new instances of classes in [fleXive], for every class
exists (or should exist ;-) ) an editable class. These editable classes can either be instantiated with
ClassName.createNew(..)
or
classInstance.asEditable()
depending on if you want to create a new instance or edit an existing.
A type, identified by its name, defines behaviour (what kind of permissions may be applied, storage model or language mode is to be used, etc.) and structure (properties and groups are assigned to types).
A system internal and somewhat special type is the "Root" type: It serves as a virtual repository to which groups or properties can be assigned, which in turn can be reused in other types or assignments without the need of inheritance.
The following is a list of parameters that can be passed as arguments to
FxTypeEdit
when editing or creating a new type:
| Parameter | Method | Create | Edit | Description |
|---|---|---|---|---|
| ACL |
setACL(ACL acl)
|
X | X | The ACL which is checked when new instances of this type are created. Will only be checked if the type is configured to check permissions. |
| Category |
setCategory(TypeCategory category)
|
X | X | A type can be assigned the categories
User
orSystem. A User categorized type can be edited by anyone with
proper roles (StructureManagement), whereas System categorized types are
ment to be [fleXive] internal and only to be changed by users with the role
GlobalSupervisor. The mode may only be changed by users with the role
GlobalSupervisor
(under ordinary circumstances changing the category of a type should never be
necessary).
|
| Check validity |
setCheckValidity(boolean checkValidity)
|
X | X | If set totrue, content instances can be assigned a
validFrom
and
validUntil
Date.
FxContent
instances provide anisValid(long time)-Method to check if they
are valid at the requested time. This feature is particularly useful in queries since
only valid content instances will be returned. Using this feature allows for instance
time triggered publication (and removal) of articles.
|
| Description |
setDescription(String description)
|
X | X | Set a description for the type. Of relevance only to user interfaces. |
| Enable parent assignments |
setEnableParentAssignments(boolean enableParentAssignments)
|
X | - | If a type is derived from another type, this flag decides if the derived assignments
should be enabled. This is by default enabled when creating a derived type:
FxTypeEdit.createNew(String name, FxString description, ACL acl, FxType parent)
and can be disabled using this method before the derived type is saved.
|
| History age |
setHistoryAge(long historyAge)
|
X | X | If
trackHistory
is enabled for this type, the
historyAge
determines the duration for which history entries exist. All entries older than
this time (in milliseconds) will be removed. History entries are changes to the type or
instances and are not fully implemented yet.
|
| Language mode |
setLanguage(LanguageMode language)
|
X | (X) | Set one of the supported language modes:
|
| Maximum destination count (Relation) |
setMaxRelDestination(int maxRelDestination)
|
(X) | (X) | Restrict the total number of instances that may be related to a source instance using
this relation type. The value
0
means unlimited. This value can only be set if the type is a relation and no instances
would invalidate this restriction.
|
| Maximum source count (Relation) |
setMaxRelSource(int maxRelSource)
|
(X) | (X) | Restrict the total number of instances that may be related to a destination instance
using
this relation type. The value
0
means unlimited. This value can only be set if the type is a relation and no instances
would invalidate this restriction.
|
| Maximum versions |
setMaxVersions(long maxVersions)
|
X | X | Set the max. number of instance versions to keep, if negative unlimited,
0
does not keep any versions.
|
| Mode |
setMode(TypeMode mode)
|
X | (X) | Set if this type is to be used as a regular type or as a relation. Changing the mode is
currently only allowed if no content instance exist.
Possible modes are:
|
| Name |
setName(String name)
|
X | X | The name of the type. Has to be unique. |
| Permissions |
setPermissions(byte permissions)
|
X | X | Set the permissions to check. The parameter contains the bitcoded types of permissions
that
should be checked. Please use the
setUseXXXPermission()-convenience methods, where XXX is Type,
Property, Step or Instance. If you want to use bit coded permissions, use these
constants:
|
| Remove instances with relation types |
setRemoveInstancesWithRelationTypes(boolean
removeInstancesWithRelationTypes)
|
- | (X) | Only applies to relations: If relation entries are removed (for instance,
you no longer want to relate Type A and B using this relation), all instances of
this relation type that relate the removed
FxTypeRelation will also be removed.
|
| State |
setState(TypeState state)
|
X | X | Changing the state allows to (de-)activate a type.
|
| Track history |
setTrackHistory(boolean trackHistory)
|
X | X | Enables history tracking (will log changes to the type itself or instances). How long
history entries are kept can be set with
setHistoryAge(long)
|
| Use instance permissions |
setUseInstancePermissions(boolean use)
|
X | X | Should instance permissions be checked? If enabled, the ACL assigned to instances will be checked. |
| Use property permissions |
setUsePropertyPermissions(boolean use)
|
X | X | Should property (assignment) permissions be checked? If enabled, the ACL assigned to property assignments will be checked. Property permission checks are disabled by default and should only be used if really necessary (i.e. if you want to hide specific company or department internal properties from users that under normal circumstances should be allowed to read the instance). |
| Use step permissions |
setUseStepPermissions(boolean use)
|
X | X | Should step permissions be checked? If enabled, the ACL assigned to workflow steps will be checked. Enable these checks if you want to prevent users from seeing/using instances in certain steps (i.e. an editor should not be allowed to edit already published articles - this is something only users from the quality assurance department should be allowed to do). |
| Use type permissions |
setUseTypePermissions(boolean use)
|
X | X | Should type permissions be checked? If enabled, the ACL assigned to this type will be checked. Disabling this check, will allow everyone to create or remove instances of this type (if instance permission checks are enabled, they will of course still be checked in the case of a removal). |
| Workflow |
setWorkflow(Workflow workflow)
|
X | (X) | Assign a workflow to this type. For existing types the workflow can only be changed if no instances exist. |
In the following example we create a new type "Customer", provide a multilingual description and assign an access control list:
Example 6.4. Creating a new FxType
TypeEngine typeEngine = EJBLookup.getTypeEngine();
FxString typeDesc = new FxString("A generic customer");
typeDesc.setTranslation(FxLanguage.GERMAN, "Ein generischer Kunde");
ACL customerACL = CacheAdmin.getEnvironment().getACL(ACL.Category.STRUCTURE.getDefaultId());
FxTypeEdit type = FxTypeEdit.createNew("Customer", typeDesc, customerACL);
typeEngine.save(type);
FxType typeByName = CacheAdmin.getEnvironment().getType("Customer");
|
We use the utility class
| |
|
The multilingual
| |
|
The german translation is assigned. | |
|
We don't want to create a new ACL and use the default ACL for structures
( | |
|
A new type instance is created with most settings using default values, only setting the name, description and ACL. | |
|
The
| |
|
This line just serves as an example how to retrieve the a reference to the new type. Saving the instance automatically forced a reload of the cached environment, that why we can retrieve it from the cache here. |
Another way to create a new type would be to use the
GroovyTypeBuilder:
Example 6.5. Creating a new FxType using the GroovyTypeBuilder
import com.flexive.shared.scripting.groovy.* import com.flexive.shared.value.* import com.flexive.shared.security.* import com.flexive.shared.* def typeDesc = new FxString("A generic customer") typeDesc.setTranslation(FxLanguage.GERMAN, "Ein generischer Kunde") new GroovyTypeBuilder().customer(description: typeDesc, acl: CacheAdmin.environment.getACL(ACL.Category.STRUCTURE.defaultId)) { } def type = CacheAdmin.environment.getType("Customer") return type.name
If executed in the Groovy-Console the code above would return CUSTOMER.
Every data type can potentially support values for different languages - depending on the properties' and property assignments' multilingual support settings.
| Data type | FxValue class | Description |
|---|---|---|
| HTML |
FxHTML
|
HTML markup. Unlimited in length. Offers the ability to use HTML editors in user interfaces. |
| String1024 |
FxString
|
A String with a maximum length of 1024 characters. Use this data type in favor of
Text
if you don't need more than 1024 characters, since usually
Text
is stored in
CLOB
Database columns while
String1024
uses
VARCHAR
columns.
|
| Text |
FxString
|
Like
String1024
but unlimited in length.
|
| Number |
FxNumber
|
Numerical type corresponding to the Java
Integer
class.
|
| LargeNumber |
FxLargeNumber
|
Numerical type corresponding to the Java
Long
class.
|
| Float |
FxFloat
|
Numerical type corresponding to the Java
Float
class.
|
| Double |
FxDouble
|
Numerical type corresponding to the Java
Double
class.
|
| Date |
FxDate
|
A date corresponding to the Java
Date
class. Note that there is no time information saved!
|
| DateTime |
FxDate
|
A date corresponding to the Java
Date
class. This data type stores date and time information.
|
| DateRange |
FxDateRange
|
A date range corresponding to two Java
Date
class instances with a start- and enddate.
Note that there is no time information saved!
|
| DateTimeRange |
FxDateTimeRange
|
A date range corresponding to two Java
Date
class instances with a start- and enddate.
Time information is saved as well using this data type.
|
| Boolean |
FxBoolean
|
A boolean value corresponding to the Java
Boolean
class.
|
| Binary |
FxBinary
|
This data type stores information about a binary content and allows streaming of that content. For more information please refer to the section called “Handling binary content” |
| Reference |
FxReference
|
A reference to a content instance, identified by its primary key
(FxPK).
|
| InlineReference |
-
|
This data type is only planned but not implemented. It will allow to create contents that do not exist on their own (and can not be loaded on their own or queried for) but embedded in another content instance. Their XPath addressing will be relative to their parent group in the embedding content. |
| SelectOne |
FxSelectOne
|
This data type allows the selection of one entry of a SelectList. See the section called “Select lists” for further information about select lists. |
| SelectMany |
FxSelectMany
|
This data type allows the selection of many entries of a SelectList. See the section called “Select lists” for further information about select lists. |
Working with binary content is like working with ordinary input- and outputstreams in Java. For uploading a
binary an
InputStream
and for downloading an
OutputStream has to be passed. Transfer of binaries is handled by [fleXive]'s own streaming
framework fxStream. It uses nonblocking tcp sockets as transport medium if the client and server part
exist in different virtual machines and is able to detect if they run within the same VM for optimal
performance.
Example 6.6. Handling binary content
File testFile = new File("src/framework/testresources/image/Exif.JPG"); FxType type = CacheAdmin.getEnvironment().getType(IMAGE_TYPE); FileInputStream fis = new FileInputStream(testFile); BinaryDescriptor binary = new BinaryDescriptor(testFile.getName(), testFile.length(), fis); //This example shows how easy it is to upload a binary programatically to theFxContent img = co.initialize(type.getId()); img.setValue("/ImageBinary", new FxBinary(false, binary)); //
img.setValue("/Filename", new FxString(false, "Exif.JPG")); FxPK pk = co.save(img); FxContent loaded = co.load(pk); FxBinary bin = (FxBinary)loaded.getValue("/ImageBinary"); File comp = File.createTempFile("Exif","JPG"); FileOutputStream fos = new FileOutputStream(comp); bin.getBestTranslation().download(fos); //
fos.close();
ContentEngine
and download it from the saved instance.
|
A
| |
|
Simply set a
| |
|
Downloading binary content is as simple as providing an
|
Select lists usually contain a set of related select items, which are used in GUIs to enable the user to make a selection of one or more of these items. [fleXive] allows in-memory creation of slim select lists for quick GUI display, as well as defining and persisting fully fledged deeply nested select lists. Names of selectlist items have to be unique within their respective list.
The following is a list of parameters that can be passed as arguments to
FxSelectListEdit
when editing or creating a new select list:
| Parameter | Method | Description |
|---|---|---|
| Parent list |
-
|
Set the parent list of this select list (used for nested select lists). Can only be set when the select list is created. |
| Name |
setName(String name)
|
Set the name of the select list (has to be unique). |
| Label |
setLabel(FxString label)
|
Set a label text to be displayed in user interfaces. |
| Description |
setDescription(FxString description)
|
Set a description text to be displayed in user interfaces. |
| Allow dynamic item creation |
-
|
May items be created dynamically (in UI's other than backends). Can only be set when the select list is created. This flag is merely used as information for UI's where users may create select list items themselves. Independent of this flag the users can only create items if they have the permission (see Table 6.7, “Relevant permissions for working with select list items” for details). |
| Create Item ACL |
-
|
The ACL which controls the permissions for adding and removing select items to the select list. Can only be set when the select list is created. |
| New Item ACL |
-
|
The ACL which is assigned to newly created items by default. Can only be set when the select list is created. |
| Default Item |
setDefaultItem(FxSelectListItem defaultItem)
|
A select list item, which is selected by default. |
The following is a list of parameters that can be passed as arguments to
FxSelectListItemEdit
when editing or creating a new select list item:
| Parameter | Method | Description |
|---|---|---|
| List |
-
|
The select list to which this select item belongs. |
| Name |
setName(String name)
|
Set the name of the item (has to be unique within the assigned list). |
| Parent Item |
setParentItem(FxSelectListItem item)
|
Set the parent item of this select list item (used for nested select lists). |
| ACL |
setAcl(ACL acl)
|
The ACL of the select item (see Table 6.7, “Relevant permissions for working with select list items” for details). |
| Label |
setLabel(FxString label)
|
Set a label text to be displayed in user interfaces. |
| Data |
setData(String data)
|
Set additional data stored in the select item. |
| Color |
setColor(String color)
|
Set the item's display color. |
| Icon Id |
setIconId(long iconId)
|
Set the id of this select list item's icon. |
| Icon version |
setIconVer(int iconVer)
|
Set the version of the icon to be displayed. |
| Icon quality |
setIconQuality(int iconQuality)
|
Set the quality of the icon to be displayed. |
The item's Life Cycle Information getLifeCycleInfo() is generated and managed by
the database and can not be edited.
As mentioned earlier, two kinds of select lists can be created. The first kind is
not suitable for being persisted and is used for example for quick display
in UI input components. FxSelectList provides
FxSelectList(String name),
createList(String name, List<? extends SelectableObjectWithLabel> items) and
createListWithName(String name, List<? extends SelectableObjectWithName> items)
for these purposes. FxSelectListItem provides
FxSelectListItem(long id, FxSelectList list, long parentItemId, FxString label)
for select list items that are not persisted.
The second kind of select lists, which can be persisted, are created via FxSelectListEdit and
its constructor or createNew(..) helper methods.
Similar to persistable select lists, persistable select list items are created via
the FxSelectListItemEdit class by invoking its constructor or its
createNew(..) method.
The persistance is handled via methods provided
by theSelectListEngine.
While only users in the role of SelectListEditor may create, update and delete select lists, select list items are handled differently. Whether a specific user is permitted to add itmes to and remove items from a specific select list is handled by the createItem ACL of the select list. Whether users may read, edit, select and deselect a specific select list item is handled by the ACL of the select item itsself. The operations and relevant permissions are specified in Table 6.7, “Relevant permissions for working with select list items”.
| Operation | ACL | Permission | Description |
|---|---|---|---|
| Creating a select list item | FxSelectList.createItemACL | CREATE |
The createItemACL of the item's select list controls which users
may create and hence add select list items to this specific select list.
|
| Deleting a select list item | FxSelectList.createItemACL | DELETE |
Similar to the creation of new select list items, the createItemACL
of the item's select list also controls which users
may remove select list items from this specific select list.
|
| Editing a select list item | FxSelectListItem.acl | EDIT | Whether a user may change the data of a specific select list item is controlled by the EDIT permission of the ACL of the select list item itsself. |
| Reading a select list item | FxSelectListItem.acl | READ | Whether a user may read a specific select list item and its data (for exmaple in the content editor) is controlled by the READ permission of the select list item. |
| Adding a select list item to a selection (when working with contents) | FxSelectListItem.acl | READ, CREATE | Whether a user may add specific select list item to his seleciton is controlled by the READ (otherwise the user wouldn't see that the item exists) and by the CREATE permission of the select list item. |
| Removing a select list item to a selection (when working with contents) | FxSelectListItem.acl | READ, DELETE | Whether a user may remove specific select list item from his seleciton is controlled by the READ (otherwise the user wouldn't see that the item exists) and by the DELETE permission of the select list item. |
Multiplicity - or often referred to as
cardinality
- defines the minimum and maximum occurance of an assignment. An assignment in the context of [fleXive] is a
group- or a property assignment. Multiplictiy is implemented in the class
FxMultiplicity
which contains some predefined and often used constants:
FxMultiplicity.MULT_0_1: zero or one occurances (optional)
FxMultiplicity.MULT_1_1: exactly one occurance (required)
FxMultiplicity.MULT_0_N: zero or more occurances (optional)
FxMultiplicity.MULT_1_N: one or more occurances (required)
The value
N
means any number of occurances.
A multiplicity of 1 to 5 elements would be coded like this:
new FxMultiplicity(1,5)
A property defines a name and a datatype (and some options). It can only exist (and is of relevance) if it is assigned to a type or group. The purpose of keeping properties and their assignments separate is the ability to share them and query across multiple types with a single property.
There are two ways to assign a property to an existing type or group:
Either by calling
FxPropertyEdit.createNew(..)
method which can clone existing or create entirely
new properties or by reusing an existing property assignment by calling
FxPropertyAssignmentEdit.createNew(..).
Example 6.7. Creating new properties
AssignmentEngine assignmentEngine = EJBLookup.getAssignmentEngine();
ACL customerACL = CacheAdmin.getEnvironment().getACL(ACL.Category.STRUCTURE.getDefaultId());
FxPropertyEdit name = FxPropertyEdit.createNew("Name",
new FxString("Name of the person"),
new FxString("Enter the persons name"),
FxMultiplicity.MULT_1_1,
customerACL,
FxDataType.String1024);
assignmentEngine.createProperty(typeId, name.setAutoUniquePropertyName(true), "/");
|
Obtain a reference to the assignment engine bean which is responsible for manipulating assignments | |
|
Get the default ACL used for structures | |
|
Create a new property with the alias "Name" | |
|
Description | |
|
Hint for user interfaces | |
|
Configure this property to be required (See the section called “Multiplicity” for more information) | |
|
Assign the ACL to be used. This ACL will only be checked if the type this property will be assigned to has property permission checks enabled | |
|
The data type will be a String with a maximum length of 1024 characters. See the section called “Data types” for an overview of available data types. | |
|
Since properties can not exist if they are not assigned to a type, we assign them to the type
with the id
|
To reuse an existing property-assignment is even simpler:
Example 6.8. Reusing property assignments
assignmentEngine.save(
FxPropertyAssignmentEdit.reuse(
"ROOT/CAPTION",
"Customer",
"/",
"AnotherCaption"),
false);
|
Obtaining a reference to the assignment engine bean is omitted in this example. We use the
| |
|
The convenience factory method
| |
|
The XPath of the assignment that is to be reused in, preceeded by the type. Here we reuse the "Caption" property that is assigned to the virtual Root-Type which acts as a repository (see the section called “Root Type” for more information about the virtual root type). | |
|
The type we want to assign it to. Please note that the type name is not case sensitive. | |
|
The new parent XPath relative to the type. Since want to assign it to the root group we use "/". Would we want to assign the property to a group called "Info" which is a subgroup of a group named "About", we'd use the XPath "/About/Info". | |
|
The
| |
|
This boolean parameter is used if the assignment is a group assignment. If set to |
The following is a list of parameters that can be passed as arguments to
FxPropertyEdit
and
FxPropertyAssignmentEdit
when editing or creating a new propery/assignment:
| Parameter | Method | Create | Edit | Description |
|---|---|---|---|---|
| ACL |
setACL(ACL acl)
|
X | X | The ACL which is checked when the type using this property or assignment is configured
to check property permissions. Setting this value for
FxPropertyAssignmentEdit
is only allowed if the referenced property allows to override its ACL.
|
| Hint |
setHint(FxString hint)
|
X | X | Set a hint text to be displayed in user interfaces. |
| In overview |
setInOverview(boolean inOverview)
|
X | X | Display in overviews. This is an option for user interfaces and a convenience method to
set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_SHOW_OVERVIEW
("SHOW.OVERVIEW") is used. The property can restrict this setting
from being overwritten in an assignment.
|
| Label |
setLabel(FxString label)
|
X | X | Set a label text to be displayed in user interfaces. |
| Multilingual |
setMultiLang(boolean multiLang)
|
X | X | Allow multilingual values for this property. This is a convenience method to
set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_MULTILANG
("MULTILANG") is used. The property can restrict this setting
from being overwritten in an assignment.
|
| Multiline |
setMultiLine(boolean multiLine)
|
X | X | A hint for user interfaces if this property should be rendered using input elements with
multiple lines. Useful for String/Text based properties (See
the section called “Data types”) which should be displayed in a
textarea instead of a single input field. Decision how to render the component is up to
the user interface. This is a convenience method to
set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_MULTILINE
("MULTILINE") is used. The property can restrict this setting
from being overwritten in an assignment.
|
| Multiplicity |
setMultiplicity(FxMultiplicity multiplicity)
|
X | (X) | Set the multiplicity of this property. Can only be changed if no instances exist that would violate the new setting. (See the section called “Multiplicity” for more information). The property can restrict this setting from being overwritten in an assignment. |
| Options |
setOption(..)
setOptionOverrideable(..)
clearOption(..)
|
X | X | Option related operations. See the section called “Property and group options”. |
| Searchable |
setSearchable(boolean searchable)
|
X | X | Allow user interfaces to use this propery/assignment in visual query editors.
This is a convenience method to set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_SEARCHABLE
("SEARCHABLE") is used.
|
| Use HTML editor |
setUseHTMLEditor(boolean useHTMLEditor)
|
X | X | Hint for user interfaces to use a HTML editor when editing values of this property. Only
makes sense for String/Text based data types.
This is a convenience method to set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_HTML_EDITOR
("HTML.EDITOR") is used.
|
| Parameter | Method | Create | Edit | Description |
|---|---|---|---|---|
| Auto unique property name |
setAutoUniquePropertyName(boolean autoUniquePropertyName)
|
X | - |
Property names have to be unique to allow querying them. Setting this option to
true
will automatically choose a name that has not been used for a propery by adding an
underscore and a running number to property names until it is unique. Set this option
only if you do not plan on "sharing" a property between different types or dont need
to query based on properties but rather property assignments.
|
| Data type |
setDataType(FxDataType dataType)
|
X | - | Set the data type of this property. Please see the section called “Data types” for more information. |
| Fulltext indexed |
setFulltextIndexed(boolean fulltextIndexed)
|
X | X | Enable fulltext indexing and queries for a property. See the section called “Fulltext search” for more information. |
| Name |
setName(String name)
|
X | - | Set the name of this property. This name is used in assignments as a proposal for the XPath alias (unless a different one is requested). Currently the name can not be changed for existing properties. To query across assignments using the same property, this name is used. |
| Overrideable ACL |
setOverrideACL(boolean overrideACL)
|
X | X | Restrict if assignments may use an ACL different from the one defined for the property.
If set to
false
an assignment may still set an ACL but the ACL of the property is used and the
assignments is ignored.
|
| Overrideable HTML editor |
setOverrideHTMLEditor(boolean overrideHTMLEditor)
|
X | X | Restrict assignment to override the HTML editor option (User interface hint).
This is a convenience method to set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_HTML_EDITOR
("HTML.EDITOR") is used.
|
| Overrideable Multilinguality |
setOverrideMultiLang(boolean overrideMultiLang)
|
X | X | Restrict assignment to override the multilinguality option (allow multilingual values).
This is a convenience method to set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_MULTILANG
("MULTILANG") is used.
|
| Overrideable Multiline |
setOverrideMultiLine(boolean overrideMultiLine)
|
X | X | Restrict assignment to override the multiline option (User interface hint).
This is a convenience method to set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_MULTILINE
("MULTILINE") is used.
|
| Overrideable multiplicity |
setOverrideMultiplicity(boolean overrideMultiplicity)
|
X | X | Restrict if assignments may override the multiplicity of this property. (See the section called “Multiplicity” for more information). |
| Overrideable Overview |
setOverrideOverview(boolean overrideOverview)
|
X | X | Restrict assignment to override the overview option (User interface hint).
This is a convenience method to set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_SHOW_OVERVIEW
("SHOW.OVERVIEW") is used.
|
| Overrideable Searchable |
setOverrideSearchable(boolean overrideSearchable)
|
X | X | Restrict assignment to override the searchable option (User interface hint).
This is a convenience method to set an option (See
the section called “Property and group options”). The constant
FxStructureOption.OPTION_SEARCHABLE
("SEARCHABLE") is used.
|
| Referenced list |
setReferencedList(FxSelectList referencedList)
|
X | (X) | If the properties data type is
SelectOne
or
SelectMany
(See
the section called “Data types”
for more information) the referenced selectlist (See
the section called “Select lists”) can be assigned. Updating an existing
property is only allowed if no data instances using the original selectlist exist.
|
| Referenced type |
setReferencedType(FxType referencedType)
|
X | (X) | If the properties data type is
Reference
(See
the section called “Data types”
for more information) the referenced type (See
the section called “Types”) can be assigned. Updating an existing
property is only allowed if no data instances using the original type exist.
|
| Unique mode |
setUniqueMode(UniqueMode uniqueMode)
|
X | (X) | Set the uniqueness level of this property. May only be changed if no content instances using this property exist. (See the section called “Uniqueness of values” for more information). |
| Parameter | Method | Create | Edit | Description |
|---|---|---|---|---|
| Alias |
setAlias(String alias)
|
X | - | Set the alias of a property assignment. Property assignments may define an alias to allow multiple use of the same property but using a different name. The alias is the rightmost part of the XPath used to address an assignment. Changing an alias for existing assignments is not supported (yet). |
| Default language |
setDefaultLanguage(int language)
|
X | X | Defining a (optional) default language preselects this language in multilingual values as the default language. |
| Default multiplicity |
setDefaultMultiplicity(int defaultMultiplicity)
|
X | X | The default multiplicity determines how many values will be initialized for an assignment. Useful in user interfaces to pre-create a set of entries instead of one. |
| Enabled |
setEnabled(boolean enabled)
|
X | (X) | Enables or disables a property assignment - making it unavailable to editors, etc. Updating an existing assignment is currently experimental and might have side-effects ... |
| Parent group assignment |
setParentGroupAssignment(FxGroupAssignment parent)
|
X | - | If this assignment is assigned to a group, the assignment of the parent group (in the context of the current type) |
| Position |
setPosition(int position)
|
X | X | Set the position of the assignment (within the same parent group). Changing an assignment's position will be update all other affected assignments within the same group. Invalid values will be adjusted (to 0 or the max. possible position) |
[fleXive] supports the following modes to enforce that a value is unique:
None: No uniqueness is enforced
Global: Globally unique across all usages of a property
Type: Unique within all instances of a type
DerivedTypes: Unique within all instances of a type, its parents and
types derived from it
Instance: Unique within a content instance
A group basically only defines a name (and some options). It can only exist (and is of relevance) if it is assigned to a type or another group. The purpose of keeping groups and their assignments separate is the ability to share them and be consistent with how properties and property assignments are handled.
Just like using properties, there are two ways to assign a group to an existing type or another group:
Either by calling
FxGroupEdit.createNew(..)
method which can clone existing or create entirely
new groups or by reusing an existing group assignment by calling
FxGroupAssignmentEdit.createNew(..).
Example 6.9. Creating a new group
AssignmentEngine assignmentEngine = EJBLookup.getAssignmentEngine();
assignmentEngine.createGroup(
typeId,
FxGroupEdit.createNew(
"Address",
new FxString("The customers address"),
new FxString("Enter the customers address here"),
true,
FxMultiplicity.MULT_1_1).
setAssignmentGroupMode(GroupMode.AnyOf),
"/");
FxPropertyEdit street = FxPropertyEdit.createNew(...);
FxPropertyEdit zip = FxPropertyEdit.createNew(...);
assignmentEngine.createProperty(typeId, street, "/Address");
assignmentEngine.createProperty(typeId, zip, "/Address");
|
Obtain a reference to the assignment engine which is needed to create groups, properties and (of course) assignments | |
|
We're about to create a new group | |
|
Since groups can not be created without assigning them to a type, we have to provide the id of the type we want to assign this group to. | |
|
The second parameter to
| |
|
"Address" is the name we chose for the new group | |
|
The label (for user interfaces) | |
|
The hint (for user interfaces again) | |
|
This parameter allows overriding the multiplicity assigned in the next line by assignments to the group | |
|
We make the group required, setting the multiplictiy to 1..1 (See the section called “Multiplicity” for more information) | |
|
This parameter is optional, since it is the default value. We set the group mode to allow
any
of the group's children to be present. An alternative would be
| |
|
We need to provide the XPath relative to the root group of the type where we want to assign the group to. Using "/" will assign it directly to the root group. | |
|
We create a property called "Street" which we want to assign to the address group later. | |
|
Same for the property "ZIP" | |
|
The "Street" property is created like in the section called “Properties and property assignments”, but we assign it to our new created group "/Address" | |
|
And again for the "ZIP" code |
Here's another example for creating groups using the
GroovyTypeBuilder
and for attaching content using the GroovyContentBuilder:
Example 6.10. Creating a new group using the
GroovyTypeBuilder
import com.flexive.shared.scripting.groovy.* import com.flexive.shared.value.* import com.flexive.shared.security.* import com.flexive.shared.* import com.flexive.shared.structure.*new GroovyTypeBuilder().person(description: new FxString("Person"),
acl: CacheAdmin.environment.getACL(ACL.Category.STRUCTURE.defaultId),
multilang: true) {
firstname(dataType: FxDataType.String1024, multilang: false, description: new FxString(FxLanguage.ENGLISH, "First name"), multiplicity: FxMultiplicity.MULT_0_N)
lastname(assignment: "PERSON/FIRSTNAME", description: new FxString(FxLanguage.ENGLISH, "Last name"), hint: new FxString(FxLanguage.ENGLISH, "Last name required"), multiplicity: FxMultiplicity.MULT_1_N)
ADDRESS(description: new FxString(FxLanguage.ENGLISH, "Address"), multiplicity: FxMultiplicity.MULT_0_N) {
street(dataType: FxDataType.String1024, description: new FxString(FxLanguage.ENGLISH, "Street (Nr)"), multiplicity: FxMultiplicity.MULT_0_N) } }
def builder = new GroovyContentBuilder("PERSON")
builder {
firstname("John")
lastname("Doe")
address {
street(new FxString(false, "Ameaningfulstreetname 444")) } }
EJBLookup.getContentEngine().save(builder.getContent())
|
Create the type "Person" using the
| |
|
.. use the default ACLs .. | |
|
.. and set the type to support multiple languages. | |
|
Create the first property "firstname". | |
|
Another property for the last name (implicitly required because auf the default multiplicity of 1..N), which is a derived assignment from "FIRSTNAME". | |
|
Here, the group "Address" having the XPath "ADDRESS" is created. Important: UPPERCASE LETTERS (Either the whole group name or simply the first letter, as in "Address") always denote the creation of a Group. | |
|
The group's only property: "street". | |
|
Retrieve a
| |
|
Call the builder passing the parameters (XPathname([contentValue]): | |
|
Set the firstname to "John". | |
|
Set the lastname to "Doe". | |
|
"Open up" the group's XPath value using "address". | |
|
Pass the value "Ameaningfulstreetname 444" to the XPath ADDRESS/STREET | |
|
Save the content by retrieving the ContentEngine EJB and calling its
|
The following is a list of parameters that can be passed as arguments to
FxGroupEdit
and
FxGroupyAssignmentEdit
when editing or creating a new group/assignment:
| Parameter | Method | Create | Edit | Description |
|---|---|---|---|---|
| Assignment GroupMode |
setAssignmentGroupMode(GroupMode mode)
|
X | (X) | Set the group mode to allow any of its possible children or just one to be present. Can only be changed for existing groups/assignments if no instances exist (See the section called “Group modes” for more information) |
| Hint |
setHint(FxString hint)
|
X | X | Set a hint text to be displayed in user interfaces. |
| Label |
setLabel(FxString label)
|
X | X | Set a label text to be displayed in user interfaces. |
| Multiplicity |
setMultiplicity(FxMultiplicity multiplicity)
|
X | (X) | Set the multiplicity of this group. Can only be changed if no instances exist that would violate the new setting. (See the section called “Multiplicity” for more information). The group can restrict this setting from being overwritten in an assignment. |
| Options |
setOption(..)
setOptionOverrideable(..)
clearOption(..)
|
X | X | Option related operations. Seethe section called “Property and group options”. |
| Parameter | Method | Create | Edit | Description |
|---|---|---|---|---|
| Name |
setName(String name)
|
X | - | Set the name of this group. This name is used in assignments as a proposal for the XPath alias (unless a different one is requested). Currently the name can not be changed for an existing group. |
| Overrideable multiplicity |
setOverrideMultiplicity(boolean overrideMultiplicity)
|
X | X | Restrict if assignments may override the multiplicity of this group. (See the section called “Multiplicity” for more information). |
| Parameter | Method | Create | Edit | Description |
|---|---|---|---|---|
| Alias |
setAlias(String alias)
|
X | - | Set the alias of a group assignment. Group assignments may define an alias to allow multiple use of the same group but using a different name. The alias is part of the XPath and is used to address an assignment. Changing an alias for existing assignments is not supported (yet). |
| Default multiplicity |
setDefaultMultiplicity(int defaultMultiplicity)
|
X | X | The default multiplicity determines how many values will be initialized for an assignment (i.e. how many groups are created upon initialization). Useful in user interfaces to pre-create a set of entries instead of one. |
| Enabled |
setEnabled(boolean enabled)
|
X | (X) | Enables or disables a group assignment - making it unavailable to editors, etc. Updating an existing assignment is currently experimental and might have side-effects ... |
| Parent group assignment |
setParentGroupAssignment(FxGroupAssignment parent)
|
X | - | If this assignment is assigned to a group, the assignment of the parent group (in the context of the current type) |
| Position |
setPosition(int position)
|
X | X | Set the position of the assignment (within the same parent group). Changing an assignments position will be upate all affected other assignments within the same group. Invalid values will be adjusted (to 0 or the max. possible position) |
[fleXive] supports the two modes for groups
OneOf
andAnyOf:
OneOf: Only one of the groups children may be present, honoring their
regular indices. This mode only makes sense if all subgroups/properties are optional!
AnyOf: Any of the groups children may be present, honoring their regular
indices. This is the default setting.
Both properties and groups allow the definition of options. These options can hold any arbitrary
String
or
Boolean
value and, if defined, the assignments to the property or group may override the value. The name of an option
must be unique.
See the API documentation of class FxStructureOption for more details.
The following options are currently actively supported:
| Constant Value | Description |
|---|---|
| MULTILANG |
Value supports multiple languages (
true
/
false
)
|
| SHOW.OVERVIEW |
Values are shown in UI overview components (
true
/
false
)
|
| HTML.EDITOR |
Value can be edited using an HTML editor in user interfaces (
true
/
false
)
|
| SEARCHABLE |
Values can be queried (this is just a hint for user interfaces!) (
true
/
false
)
|
| MAXLENGTH |
Values that support a maximum input length (currently only
String1024
and
Text
) will be rendered with input length restrictions when editing.
|
| MULTILINE | Render a textarea instead of a single input line. If the value is greater than 1 it determines the number of rows. |
[1] Imagine an online-shop scenario with different kinds of articles, each implemented using their own type. Something they have in common is their name. Instead of having to build a query for searching the name property that is an OR-construct including all involved types it would be easier to assign to all types a property called "name" and query this property instead of the assignments.