Introduction
Generic Placeholders allow to use one placeholder for several purposes. In this documentation, we describe, how to enable and configure Generic Placeholders in a priint:publishing server environment.
This documentation adresses Comet project configurators and Java developers as well. The concept is described by three common use cases in section Examples, implementation of these use cases is explained in section Example Implementation.
If you are not that interested in background information, you can skip the first sections and directly proceed with Examples.
If you already know all about the Generic Placeholder and Function Variable concept, you can directly shift to the reference sections ISON: Definition of Function Variables resp. Java: Declaration of Function Variables.
Requirements
Generic Placeholders are supported from priint:publishing server and priint:comet plug-in Version 4.1. Please use the latest available release; while basic functionality should work with any 4.1 version, the full functionality as described in this documentation requires
- priint:publishing server 4.1 Build >= 3710
- priint:comet ID plug-ins 4.1 resp. priint:renderer >= R18200
Generic Placeholders / Function Variables Overview
Base technology for Generic Placeholders is a priint:comet plug-in feature introduced in version 4.1 named Function Variables. Function Variables allow to parameterize placeholders and thus modify the statements, which are used to load, store or synchronize this placeholder. In other words, one placeholder configuration can be used for several type of data - depending on the actual values, which are set for the variables of a placeholder instance in the document.
Values can be assigned using the new Function variables area in the Placeholder Values panel (see highlighted area in screenshot below).
Technical Background
From the Renderer point of view, Function Variables are just special cscript directives preceding a placeholder statement or script. They start with #pragma var
(for each variable definition in a single line), followed by the variable, optionally label and optionally a list of values to show up in the variable DropDown menu.
Example
(The highlighted area shows the Function Variable definition)
There are two variables defined in this example: templateId and resultEntityId.#pragma var "templateId//Template" "268477081//Product Label Green" "268477090//Product Label Yellow" "67108961//article.template" #pragma var "resultEntityId//Result Entity Id" "//Default" "colour//Colour" "keyvaluegroup//Keyvalue Group" "print_product_group//Print Product Group" "size//Size"getlist elements plugin(globalName='DataProviderManager',methodName='get')[<Session.Id>,'MultiframeData',<Model.Id>,<Entity.Id>,<resultEntityId>,<Record.Id>,<Record.GroupId>,'','','','','',<xml.publication>,'','',<xml.documentId>,{'<Variable.templateId>' => <templateId>}, <Java.ResultClass>]:placeholder#268468732#get
When processing this placeholder statement, each occurence of <templateId> resp. <resultEntityId> is replaced by the actual value set for this variable in this placeholder instance.
In a cscript, the values of the Function Variables are available as global const char *
variables, and can be used like this:
int main() { showmessage ("templateId=%s, resultEntityId=%s", templateId, resultEntityId); return 0; }(just to get the idea, of course this script does not make much sense).
priint:publishing server Integration
In a priint:publishing server environment, placeholder statements are usually generated from the placeholder configuration.
For Function Variables, we introduced a new tag schema, which allows to expose any parameter of a DataProcessing or DataMapping method in the placeholder processing chain as Function Variable:
<Variable.Identifier>If the value of a parameter matches this schema, a Function Variable definition is added for this parameter, also the statement is expanded, so that values set for this Function Variable in a particular placeholder instance in the document are propagated back to the method, which defined this Function Variable parameter.
Sounds complicated, but probably will get quite obvious with the following example.
Example:
We add the DataProcessing method formatPrice to a price placeholder. This method takes three parameters
List<String> input
set to <Entity.ResultList>. This is the result of the DataProvider.get call or the result of a previous DataProcessing method in the processing chain. In most configurations, this value will be left unchanged.String decimalPlaceCharacter
this is supposed to be configured in ISON, e.g. set to "," or ".".String formatString
also supposed to be configured in ISON
<Variable.DecimalPlaceCharacter>
, this parameter is exposed as a Function Variable and can be set in the document for each particular placeholder.
priint:publishing server Integration II
In priint:publishing server Integration we showed, how to define Function Variables in ISON, but it should be more common to declare Function Variables in the Java code of a DataMapping or DataProcessing method (detailed description in the examples below and in section Java: declaration of Function Variales).
The idea is, that in most cases the Java developer should know, if a parameter of the method is suitable for being exposed as a Function Variable or not. Also, he should know about value ranges or value lists applicable for a parameter, so usually the best place to declare Function Variables would be in the Java code.
Declaring Function Variables in the Java Code also allows to define or calculate value lists for the DropDowns in the Placeholder Values panel, show user readable labels instead of parameter names etc.
Naming Conventions
According to the naming conventions of ParameterTags (see PubServerSDK documentation for the ParameterTags class), the Identifier part of the tag- must be a valid identifier
- should start with an upper case character
- <Variable.TemplateId>: valid
- <Variable.Template Id>: invalid, identifiers must not contain white spaces
- <Variable.123TemplateId>: invalid, identifiers must start with a letter (rather than digit)
- <Variable.templateId>: works, but not conform to naming conventions
- <Variable.Template-Id>: invalid, identifiers must consist only of letters, digits and the underscore character
- <variable.TemplateId>: invalid, has to be Variable rather than variable
The name of the identifier of the parameter used in the document (and in statements) is derived from the identifier part of the tag: it is simply the first character in lowercase, the rest of the identifier unchanged.
This is to meet cscript conventions for variable names, also in the renderer tags with lowercase first character are more common.
Examples:
- the placeholder tag for
<Variable.TemplateId>
will be<templateId>
- the cscript variable name for
<Variable.TemplateId>
will also betemplateId
Examples
The following examples use standard DataMapping and DataProcessing methods delivered with priint:publishing server.
We assume, that an entity model and Comet project already exist, also some example data would be nice. In that regard, the output on your system probably will differ from the result shown in the examples.
The configuration of all other resources (DataProvider, placeholder, templates, Java methods) is described in the section Example implementation, so at least it should be possible to achieve equivalent results in your environment.
Generic KeyValue
We use this generic placeholder to retrieve any type of KeyValue data associated to a bucket.
See Generic KeyValue implementation for details.
The placeholder defines two Function Variables:
- key (Key): which particular key should be loaded for this placeholder? Unknown keys will result in an empty value, {*} will just return the first value found.
- designator (Designator): in which format should the value be returned? This is a standard list of supported formats, see section Methods and resources for value lists for details.
Because the list of available keys is dynamic (i.e. depending on the document context resp. bucket linked to the placeholder), we cannot predefine or use a Java method to provide a list of values for this variable (except for the default value Any key), but have to enter an appropriate key manually instead.
Usage of Generic KeyValue placeholder
In a text frame, we create a text placeholder of type "Generic KeyValue" (configuration of this placeholder see Generic KeyValue implementation).
In the Place Holder Values panel, we can see the list of Function Variables, which can be configured for this placeholder (the text cursor must be somewhere in the range of this placeholder or parts of this placeholder must be selected). By clicking the lock item at the top of the list, values can be edited - either by selecting an entry of the DropDown menu in the Value column or by typing a value in the Custom value column (when clicking in the cell, a text input field should appear).
To save the new values, click the lock button again while pressing down the ALT-key.
Load result with key=compatibility and designator=Value with unit
We set key to "compatibility" and designator to "Value with unit", save and link this placeholder with a product:
Load result with key=complete_length and designator=Value without unit
We set key to "complete_length" and designator to "Value without unit", save and reload this placeholder:
Generic Attribute
This placeholder allows us to load all types of text entities using the same placeholder configuration. While other examples require definition of Function Variables as parameters for certain DataMapping or DataProcessing methods, this example works out of the box: the variable definition is generated automatically, if the Result Entity Id field in the placeholder configuration is left (or set to) empty.
See Generic Attribute Implementation for details.
The placeholder defines one function variable:
-
resultEntityId (Result Entity Id): identifier of the entity, which should be included in the result.
Predefined values are all entities applicable for the result type of the DataQuery method assigned to this placeholder.
The first entry ("Default") sets an empty string as resultEntityId, which provides the same behaviour like in "old" configurations, when no resultEntityId was set in the placeholder configuration.
Usage of Generic attribute placeholder
In a text frame, we create a text placeholder of type "Generic attribute" (configuration of this placeholder see Generic Attribute Implementation).
In the Place Holder Values panel, we can see the list of Function Variables, which can be configured for this placeholder (the text cursor must be somewhere in the range of this placeholder or parts of this placeholder must be selected). By clicking the lock item at the top of the list, values can be edited - either by selecting an entry of the DropDown menu in the Value column or by typing a value in the Custom value column (when clicking in the cell, a text input field should appear).
To save the new values, click the lock button again while pressing down the ALT-key.
Load result with resultEntityId=product_application
We set resultEntityId to "product_application", save and link this placeholder with a product:
Load result with resultEntityId=product_description
We set resultEntityId to "product_description", save and reload this placeholder:
Template Selector
In this example, we use a Multiframe placeholder to build sub elements. We add a DataProcessing method to the placeholder configuration, which allows to choose the templates for sub elements via a function variable. This DataProcessing method is included in the standard delivery, see Template Selector Implementation for details.
The placeholder defines two function variable:
- templateId (Template): identifier of the template, which should be used to create sub elements.
- resultEntityId (Result Entity Id): see the Generic Attribute example for details.
Usage of Template Selector
We create a frame and tag it as a Multiframe placeholder (configuration of this Multiframe placeholder see Template Selector Implementation).
In the Place Holder Values panel, we can see the list of Function Variables, which can be configured for this placeholder (the frame must be selected). By clicking the lock item at the top of the list, values can be edited - either by selecting an entry of the DropDown menu in the Value column or by typing a value in the Custom value column (when clicking in the cell, a text input field should appear).
Load result with template=Product Label Green
We set template to Product Label Green, link the frame with a product and execute Repeating elements > Create sub elements of selected products of the Product Pool panel menu while the frame is selected.
Note: we leave resultEntityId empty, thus we can use this frame for any entity type. The DataProvider of the example configuration just loads all direct child buckets of a given bucket.
Load result with template=Product Label Yellow
We change template to Product Label Yellow, clear the sub elements created before and run Repeating elements > Create sub elements of selected products of the Product Pool panel menu again:
Example Implementation
Generic KeyValue Implementation
Implementation of this placeholder consist of three parts:
- DataMapping method, which declares the key and designator Function Variables
- DataProvider for KeyValues using this DataMapping method
- Placeholder, which uses this DataProvider
Generic KeyValue for Project Configurators
Follow these configuration steps:
- In the ISON DataProvider Explorer, create a new DataProvider:
-
Use Label="Generic KeyValue", Identifier="genericveyvalue" and Entity class="Bucket":
-
In the DataProvider editor, click the "Choose" button to choose a DataQuery method. Select "getEntityKeyValuesOfBucket" from the EntityManager plug-in:
-
Change to the DataMapping tab and click the "Choose" button to choose a DataMapping method. Select "firstKeyValueByKeyToString" from the DataMappingToString plug-in:
- Save and checkin the DataProvider
-
In the ISON CometExplorer, create a new Placeholder:
-
Set Name="Generic KeyValue" and Type=TEXT (also choose an appropriate description and category):
-
In the Placeholder editor, click the "Choose" button next to the DataProvider field and select the "Generic KeyValue" DataProvider we just created:
As you like, you can also set the Result Entity Id, if you want to load KeyValues of a certain entity only. - Save and checkin the placeholder.
If this is the case, you can use the newly created Generic KeyValue placeholder out of the box as shown in the Generic KeyValue example.
Why isn't there any more configuration required?
This is, because the Java developer did all the job and added appropriate annotations to the Parameter declarations in the Java class. If this is the case, Function Variables are automatically defined for the DataProvider resp. Placeholder once you use this method in your configuration.
If this is not the case, you can still define Function Variables for certain parameters, though there are some limitations regarding value lists and variable naming. See ISON: Configuration of Generic Placeholders for details.
Generic KeyValue for Java Developers
Though the DataMapping method we use here is part of the standard delivery (and therefore no extra Java implementation is required for this example), the relevant code fragments are explained in the following.
Note:
The example is taken from the DataMapping plug-in, which is part of the standard delivery. For demonstration purposes, the code has been slightly simplified.
Requirements
- Function Variables can be declared for PubServerMethods only; therefore the method, which declares a Function Variable must be annotated as @PubServerMethod and must be enclosed in a class annotated as @PubServerPlugin
- Parameters of this method must be annotated as @PubServerMethodParameter. This is a general requirement for PubServerMethods also.
Remarks
- We use a special Tag annotation for Function Variables, the general format is
<Variable.Identifier>
. If a parameter is set to a value matching this pattern, the CometBridge will generate a Function Variable definition for this parameter (no matter, if this is declared in the Java parameter annotation as shown below or just configured in ISON).
By setting the defaultValue attribute to <Variable.Key>, the default value when embedding this method in a DataProvider or Placeholder configuration will be <Variable.Key> also, so on the ISON side no further configuration is necessary. - the optional attribute value allows definition of value lists for this parameter. The first entry in the value list (Custom) will always be present, this allows to enter custom values for a particular placeholder in the InDesign document (so as the Java developer you should be aware, that there is no guarantee that one of the values provided in the value list will be passed to the method call).
Value lists can originate from several sources:- Value.Type.INLINE: values are defined inline in the method parameter annotation (as shown in the example below).
- Value.Type.PLUGIN: values are provided from a Java mthod call (as shown in the third example)
- Value.Type.CONFIG: values are defined in a configuration file in the Jackrabbit repository (this feature is not yet implemented)
- In this case, values are defined INLINE, so we expect a list of or just one (or none, if only the Custom entry should be shown) @ValueItems, each one described by an identifier - this is the value passed to the Java method call, if this entry is selected - and a label - this is the value shown in the popup in the placeholder configuration. Both should (but do not have to) be unique.
import com.priint.pubserver.plugin.annotation.Value; import com.priint.pubserver.plugin.annotation.ValueItem; @PubServerPlugin
public class DataMappingToString extends PluginControlDefault { /** * Returns designated field(s) of first KeyValue with given key in input list * * @param keyValues List of KeyValues to be converted * @param key filter KeyValues by this, '{*}' for 'Any key' * @param designator String 'ValueWithoutUnit', 'ValueWithUnit', etc. * @return String list with one or no element * @throws PubServerException */ @PubServerMethod( type = PluginMethod.MethodType.DATA_MAPPING, label ="firstKeyValueByKeyToString", description = "Returns designated field(s) of first KeyValue" + " with given key in input list") public List<String> firstKeyValueByKeyToString( @PubServerMethodParameter( name = "keyValues", defaultValue="<Entity.ResultList>", description="result of query") List<KeyValue> keyValues, @PubServerMethodParameter( name = "key", defaultValue="<Variable.Key>", // Remark (1) description="filter KeyValues by this", value=@Value( // Remark (2) type=Value.Type.INLINE, label="Key", values={ // Remark (3) @ValueItem(identifier="{*}",label="Any Key") } )) String key, @PubServerMethodParameter( name = "designator", defaultValue="<Variable.Designator>", description="Designator for the output format", value=@Value( type=Value.Type.INLINE, label="Designator", values={ @ValueItem(identifier="ValueWithoutUnit", label="Value without unit"), @ValueItem(identifier="ValueWithUnit", label="Value with unit"), @ValueItem(identifier="Label", label="Label"), @ValueItem(identifier="Unit", label="Unit"), @ValueItem(identifier="Symbol", label="Symbol"), @ValueItem(identifier="ParentIdentifier", label="Parent identifier"), @ValueItem(identifier="LabelValueWithUnit", label="Label, value with unit") } )) String designator) throws PubServerException { List<String> resultlist = new ArrayList<String>(); String result = ""; if (keyValues == null || keyValues.isEmpty()) { return resultlist; } for (KeyValue kv : keyValues) { if ( (key != null && key.equals(DataMappingToString.MATCH_ALL)) || (kv.getKey() != null && kv.getKey().equals(key))) { result = getDesignatedFieldFromKeyValue (kv, designator); } } resultlist.add(result); return resultlist; }
Generic Attribute Implementation
Implementation of this placeholder works out of the box for any placeholder.
Generic Attribute for Project Configurators
There isn't much to regard for project configurators when configuring a "Generic attribute" placeholder. All you have to do, is leave the Result Entity Id field empty, see screenshot below.
If the Result Entity Id is empty, variable definitions are added automatically, when generating statements resp. processing scripts for this placeholder. In this case, the Result Entity Id can be set in the Placeholder Values panel as shown in example Generic Attribute.
The DropDown contains all entities, which match the result type of the DataProvider query method set for this placeholder, i.e.: if the query returns KeyValues, the DropDown list contains all KeyValue entities.
Generic Attribute for Java Developers
There is nothing to do for the Java developer for this example. Function Variable support for the Result Entity Id is a "built-in" feature and there is no other proposed solution to access the resultEntityId attribute of a placeholder in any other way than the auto-generated variable definitions, if unset.
However, this is a good example for context sensitive ValueList provider methods, so it is worth to take a look at the getEntities implementation, which provides the list of entities applicable for this placeholder.
Example: placeholder sensitive ValueList provider method
Note:
Again, this is a real life example, which - for demonstration purpose - has been slightly simplified. Particularly, all failure check has been removed from the code below (and there are lots of possible failures ... starting with incomplete placeholder configurations etc.).
Remarks
- we need to access some of the priint:publishing server resources and therefore first get the appropriate managers.
The code may look somewhat complicated at a first glance, but this is in the nature of things, when dealing with placeholders. - certain properties are predefined in the parameters Map, see Value List from Method for details.
package com.priint.pubserver.comet.bridge.value; import com.priint.pubserver.comet.config.CometConfigurationLocal; import com.priint.pubserver.comet.entity.CometProject; import com.priint.pubserver.comet.entity.placeholder.CometPlaceholder; import com.priint.pubserver.comet.util.ConfigUtils; import com.priint.pubserver.comet.util.PathUtils; import com.priint.pubserver.entity.Entity; import com.priint.pubserver.entity.EntityModel; import com.priint.pubserver.exception.PubServerException; import com.priint.pubserver.plugin.PluginControlDefault; import com.priint.pubserver.plugin.PluginMethod; import com.priint.pubserver.plugin.PluginUtils; import com.priint.pubserver.plugin.ValueItem; import com.priint.pubserver.plugin.annotation.PubServerMethod; import com.priint.pubserver.plugin.annotation.PubServerMethodParameter; import com.priint.pubserver.plugin.annotation.PubServerPlugin; import com.priint.pubserver.plugin.interfaces.DataProviderManagerLocal; import com.priint.pubserver.plugin.interfaces.EntityManagerLocal; import com.priint.pubserver.util.Constants; import com.priint.pubserver.util.ValueUtils; @Stateless(mappedName=ValueDefinitions.MAPPED_NAME) @PubServerPlugin public class ValueDefinitions extends PluginControlDefault { private static final Logger LOGGER = LoggerFactory.getLogger(ValueDefinitions.class); @PubServerMethod(type=PluginMethod.MethodType.VALUE_LIST) public List<ValueItem> getPlaceholderEntities( @PubServerMethodParameter(name="parameters") Map<String,Object> parameters) throws PubServerException { List<ValueItem> result = new ArrayList<ValueItem>(); // Remark (1) String sessionId = PluginControlDefault.getSessionId(); EntityManagerLocal entityManager = PluginUtils.getPlugin(Constants.MANAGER_ENTITY, sessionId, EntityManagerLocal.class); DataProviderManagerLocal dataproviderManager = PluginUtils.getPlugin(Constants.MANAGER_DATAPROVIDER, sessionId, DataProviderManagerLocal.class); CometConfigurationLocal cometConfiguration = PluginUtils.getPlugin(CometConfigurationLocal.MAPPED_NAME, sessionId, CometConfigurationLocal.class); // 1st step: get the placeholder we are processing this ValueList for // Remark (2) Integer placeholderId = (Integer)parameters.get(CometConfigurationLocal.ENV_PLACEHOLDER_PROPERTY); String relativePath = PathUtils.getProjectRelativeContainerPath(placeholderId, CometPlaceholder.class); String absolutePath = cometConfiguration.getAbsolutePath(relativePath); CometPlaceholder placeholder = ConfigUtils.getEmbeddedEntity( cometConfiguration.getItem(absolutePath, CometPlaceholder.class), CometPlaceholder.class); // 2nd step: get the result type from the DataProvider set for this placeholder String dataproviderId = placeholder.getDataProvider().getIdentifier(); Class<?> returnType = dataproviderManager.getDataProviderGetterQueryReturnTypeArgument(dataproviderId); // 3d step: get EntityModel from the CometProject we are connected with CometProject project = cometConfiguration.getSessionProject(); String entityModelName = project.getEntityModel(); EntityModel entityModel = entityManager.getEntityModel(entityModelName); // 4th step: add all matching entities to the result list ... for (Entity entity : entityModel.getEntities().values()) { if (entity.getEntityDataClass().equals(returnType)) { result.add(new ValueItem(entity.getIdentifier(), entity.getLabel())); } } // ... sort and return ValueUtils.sortAscending(result); return result; } }
Template Selector Implementation
This placeholders requires
- a DataProvider, which returns Elements
- a MUTLIFRAME placeholder with the "setTemplate" method in the processing chain
- one or several templates, which can be used for sub elements
Template Selector for Project Configurators
The Template selector implementation is very similar to the Generic KeyValue Implementation shown above. Therefore, we omit screenshots and just do with a simple step-by-step description:
- In the ISON DataProvider Explorer, create a new DataProvider
- Use Label="Child Buckets As Elements", Identifier="childbucketsaselements" and Entity class="Bucket".
- In the DataProvider editor, click the "Choose" button to choose a DataQuery method. Select "getEntityChildBuckets" from the EntityManager plug-in.
- Change to the DataMapping tab and click the "Choose" button to choose a DataMapping method. Select "bucketsToElements" from the DataMappingToElement plug-in.
- Save and checkin the DataProvider
- In the ISON CometExplorer, create a new Placeholder.
-
Set Name="Child Buckets" and Type=MULTIFRAMES (also choose an appropriate description and category):
- In the Placeholder editor, click the "Choose" button next to the DataProvider field and select the "Child Buckets As Elements" DataProvider we just created. As you like, you can also set the Result Entity Id, if you want to load buckets of a certain entity only.
- Change to the DataProcessing Load tab, right-click in the function list and select "Add" to add a DataProcessing method.
- In the dialog, select the "setTemplate" method from the CometElementFunctions plug-in and click "Ok".
- Save and checkin the placeholder.
There is no more configuration required on the ISON side. Once you relogin from InDesign (or click the "Search" button in the InDesign Placeholder panel while pressing down the ALT key), you should find Child Buckets in the list of placeholders.
Before you can use this placeholder, you should also create appropriate templates for the sub elements in InDesign. After creating these templates, you have to reload the Placeholder panel again (click "Search" button while pressing down the ALT key); after that you can use this placeholder like shown in Template Selector example above.
Template Selector for Java Developers
The Java implementation of the Template selector example consists of two parts:
- DataProcessing method with appropriate parameter annotations
- ValueList method, which provides the list of templates
DataProcessing method setTemplate
Remarks:
- by convention, the result list of previous methods in the processing chain is the first parameter.
- optional name attribute, this has no further effect on the Function Variable behaviour.
- this value will be used as default when adding the method to a configuration (DataProvider or Placeholder). If the parameter should be exposed as a Function Variable, the default value must start with the
<Variable.
prefix. The identifier of the Function Variable is derived from this value, see PubServerMethodParameter Annotation for details. - source for the value list is a plug-in method. In this case, the attributes pluginMappedName and methodName must also be provided.
package com.priint.pubserver.comet.bridge.dataprocessing; import java.util.List; import javax.ejb.Stateless; import com.priint.pubserver.comet.bridge.entitydata.Element; import com.priint.pubserver.comet.bridge.value.CometValueDefinitionsLocal; import com.priint.pubserver.parameterparser.ParameterTags; import com.priint.pubserver.plugin.PluginControlDefault; import com.priint.pubserver.plugin.PluginMethod; import com.priint.pubserver.plugin.annotation.PubServerMethod; import com.priint.pubserver.plugin.annotation.PubServerMethodParameter; import com.priint.pubserver.plugin.annotation.PubServerPlugin; import com.priint.pubserver.plugin.annotation.Value; import com.priint.pubserver.tracing.Tracer; import com.priint.pubserver.tracing.TracerFactory; @Stateless @PubServerPlugin public class CometElementFunctions extends PluginControlDefault { private static final Tracer TRACER = TracerFactory.getTracer(CometElementFunctions.class); @PubServerMethod( type = PluginMethod.MethodType.DATA_PROCESSING, description="Applies a template Id to a list of elements.") public List<Element> setTemplate( @PubServerMethodParameter( name="inputList", defaultValue=ParameterTags.Tag.ENTITY_RESULTLIST, description="List of elements") List<Element> inputList, // Remark (1) @PubServerMethodParameter( name="templateId", // Remark (2) defaultValue="<Variable.TemplateId>", // Remark (3) description="Id of the template", value=@Value( type=Value.Type.PLUGIN, // Remark (4) label="Template", pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getTemplates )) int templateId) { TRACER.info(this.getClass().getSimpleName(), "", "inputList={}, templateId={}", inputList, templateId); for (Element e : inputList) { e.setTemplateId(templateId); } return inputList; } }
ValueList provider method getTemplates
Remarks:
public List<ValueItem> methodName(Map<String,Object> parameters)
The method is allowed to throw any PubServerException (which will be handled when processing this method).
package com.priint.pubserver.comet.bridge.value; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; import com.priint.pubserver.comet3.entity.PageItem; import com.priint.pubserver.exception.PubServerException; import com.priint.pubserver.plugin.PluginControlDefault; import com.priint.pubserver.plugin.PluginMethod; import com.priint.pubserver.plugin.ValueItem; import com.priint.pubserver.plugin.annotation.PubServerMethod; import com.priint.pubserver.plugin.annotation.PubServerMethodParameter; import com.priint.pubserver.plugin.annotation.PubServerPlugin; import com.priint.pubserver.util.ValueUtils; @Stateless @PubServerPlugin public class CometValueDefinitions extends PluginControlDefault { @PubServerMethod(type=PluginMethod.MethodType.VALUE_LIST) // Remark (1) public List<ValueItem> getTemplates( @PubServerMethodParameter(name="parameters") Map<String,Object> parameters) // Remark (2) throws PubServerException { List<ValueItem> result = new ArrayList<ValueItem>(); Map<String,PageItem> pageitems = this.getPageItemHash(); for (PageItem it : pageitems.values()) { result.add(new ValueItem(it.getId() + "", it.getName())); } ValueUtils.sortAscending(result); return result; } }
ISON: Definition of Function Variables
Most of it has already been said in priint:publishing server Integration.
Summary:
- any parameter of a DataMapping or DataProcessing method can be exposed as a Function Variable by setting the value for this parameter according to the schema
<Variable.Identifier>
- configuration capabilities are limited in that case, we cannot define custom labels nor value lists, which are shown in the DropDown in the Placeholder Values panel for this parameter
- there are certain naming conventions described in section Naming Conventions
The most common way to use Function Variables will probably be, to just add DataMapping or DataProcessing methods to the DataProvider resp. placeholder, which already declare Function Variables in the Java code of these methods.
In this case, you can leave the configuration unchanged and everything works like supposed by the Java developer.
There are three situations, when a Comet project configurator might want to manually change Function Variable support:
- disable Function Variable support for a certain parameter and "hard code" the value in ISON. This can simply be done by replacing the
<Variable.Identifier>
by any other value in the configuration of this method. - enable Function Variables for a parameter, which is not declared as Function Variable. This can simply be done by setting the value for this parameter to
<Variable.Identifier>
in the configuration of this method. - name clashes: two or more methods in the processing chain use the same identifier for Function Variables. This - of course - cannot work, at least, it will not work as expected (whatever exactly we expect in this case). You can change the identifier part of any of the affected parameters, the good news is: all other declarations (label, value list etc.) will be preserved.
Java: Declaration of Function Variables
In this section, we describe the Java resources required for Function Variable support.
As already mentioned, Function Variables can be declared for any parameter of a DataMapping or DataProcessing method. Whenever this method is included in a DataProvider or placeholder configuration, the Function Variable will be available out of the box.
DataMapping and DataProcessing method implies the following requirements:
- the method is defined in a Stateless or Singleton bean annotated as @PubServerPlugin
- the method is annotated as @PubServerMethod
- all parameters of this method are annotated as @PubServerMethodParameter
@PubServerMethodParameter Annotation
package com.priint.pubserver.plugin.annotation;
public @interface PubServerMethodParameter
The @PubServerMethodParameter annotation is the general annotation for any parameter of any @PubServerMethod and documented in the PubServerSDK. Some of the attributes are relevant for Function Variable declaration and therefore described here:
-
String defaultValue
: for Function Variables, this should be set according to the schema<Variable.Identifier
. Note, that the Function Variable identifier is derived from the identifier part of this value, see Naming Conventions for details.. -
Value value
: allows further declarations (label, value lists) for this parameter, if it is exposed as a Function Variable, see @Value Annotation
@Value Annotation
package com.priint.pubserver.plugin.annotation;
public @interface Value
The @Value annotation allows declaration of Function Variable labels and value lists for this Function Variable.
The relevant attributes are described here:
-
Type type
: with Type=public enum Type { INLINE, PLUGIN, CONFIG, UNDEFINED }
Defaults to Value.Type.INLINE. Describes, how the value list for this value is obtained. String pluginMappedName
: mapped name of the plug-in, if type is Value.Type.PLUGIN, in this case mandatory, defaults to empty.String methodName
: name of the ValueList provider method, if type is Value.Type.PLUGIN, in this case mandatory, defaults to empty.
The signature of the ValueList provider method must be as follows:public List<ValueItem> methodName(Map<String, Object> parameters)
ValueMethodParameter[] methodParameters
: array of parameters, which should be passed to the method. A @ValueMethodParameter defines a key / value pair, which will be tranferred to a Map<String,Object>, when the method is called to retrieve value lists. Defaults to empty array.
See Value List from a Method for example.ValueItem[] values
: values for the value list of this parameter, if type=Value.Type.INLINE. See Value List Inline for example.
Defaults to empty array.String label
: label for te function variable, which will be shown in the UI
Empty Value List / no Drop Down
No values (except for the "Custom" entry, which will always be present) should be shown in the DropDown for a Function Variable.
This can be achieved very simple:
- set the type attribute of the @Value annotation to Value.Type.INLINE
- omit the values attribute of the @Value annotation
Value List Inline
We use this value type, if we have a fixed set of values (however, if these values are used for several Function Variables, it can still make sense to define a method, which returns this list).
To use fixed / inline lists of values
- set the type attribute of the @Value annotation to Value.Type.INLINE
- define the values in the values attribute of the @Value annotation as shown below
@PubServerMethodParameter( name = "designator", defaultValue="<Variable.Designator>", description="Designator for the output format", value=@Value( type=Value.Type.INLINE, label="Designator", values={ @ValueItem(identifier="ValueWithoutUnit", label="Value without unit"), @ValueItem(identifier="ValueWithUnit", label="Value with unit"), @ValueItem(identifier="Label", label="Label"), @ValueItem(identifier="Unit", label="Unit"), @ValueItem(identifier="Symbol", label="Symbol"), @ValueItem(identifier="ParentIdentifier", label="Parent identifier"), @ValueItem(identifier="LabelValueWithUnit", label="Label, value with unit") } )) String designator)
Value List from Method
Values are provided by a ValueList provider method. This method must match the following signature:
public List<ValueItem> methodName(Map<String, Object> parameters)
Also, the method must be annotated as @PubServerMethod with PluginMethod.MethodType.VALUE_LIST.
Note:
The return type of ValueList methods must be
List<com.priint.pubserver.plugin.ValueItem>
rather than
List<com.priint.pubserver.plugin.annotation.ValueItem>
Example: fully annotated ValueList provider method:
@PubServerMethod(type=PluginMethod.MethodType.VALUE_LIST) public List<ValueItem> getTemplates( @PubServerMethodParameter(name="parameters") Map<String,Object> parameters);
The method is allowed to throw a PubServerException. Other exceptions should be handled in the method itself.
Relevant @Value attributes
pluginMappedName
: mapped name of the plug-in, which serves the method, mandatorymethodName
: name of the ValueList provider method, mandatorymethodParameters
: parameters to pass to this method, optional
The following parameters are provided by the priint:publishing server when calling this method:
CometConfigurationLocal.ENV_PLACEHOLDER_PROPERTY
: the Id of the placeholder currently being processed.CometConfigurationLocal.ENV_SUBJECT_PROPERTY
: subject of the statement currently being processed. This can be "get", "set" or "sync"CometConfigurationLocal.SESSION_CLIENT_PROPERTY
: client of the current sessionCometConfigurationLocal.SESSION_PROJECT_PROPERTY
: identifier of the Comet project, we are connected to in the current sessionCometConfigurationLocal.SESSION_REGION_PROPERTY
: region of the current sessionCometConfigurationLocal.SESSION_LANGUAGE_PROPERTY
: language of the current session.
methodParameters
attribute, see example below.
@PubServerMethodParameter( name="templateId", defaultValue="<Variable.TemplateId>", description="Id of the template", value=@Value( type=Value.Type.PLUGIN, label="Template", pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, // it is a good idea to define constants methodName=CometValueDefinitionsLocal.getTemplates, // for plug-in and method names... methodParameters={ @ValueMethodParameter(key="templateDomain",value="all"), @ValueMethodParameter(key="pageType",value="anyPage"), } )) int templateId)
Value List from Configuration File
In future versions, it will also be possible to load value lists from certain configuration files. At the time of this writing, this is not yet implemented.
Standard Methods supporting Function Variables
There are a couple of methods in the standard delivery, which already support Function Variables. Also a (small) set of ValueList provider methods is included.
Methods and Resources for Value Lists
Methods defined in com.priint.pubserver.datamapping.DataMappingValueDefinitionsLocal (PubServerSDK):
getKeys(Map<String, Object>)
Gets keys. Actually, this will just return the MATCH_ALL entry, because (as explained in the example above), keys are "dynamic" and, at the time, cannot be retrieved from EntityManager.
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=DataMappingValueDefinitionsLocal.MAPPED_NAME, methodName=DataMappingValueDefinitionsLocal.getKeys // ...
getKeyValueDesignators(Map<String, Object>)
Gets the standard set of key designators.
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=DataMappingValueDefinitionsLocal.MAPPED_NAME, methodName=DataMappingValueDefinitionsLocal.getKeyValueDesignators // ...
getMediaFormats(Map<String, Object>)
Gets available media formats.
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=DataMappingValueDefinitionsLocal.MAPPED_NAME, methodName=DataMappingValueDefinitionsLocal.getMediaFormats // ...
getMediaTypes(Map<String, Object>)
Gets available media types
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=DataMappingValueDefinitionsLocal.MAPPED_NAME, methodName=DataMappingValueDefinitionsLocal.getMediaTypes // ...
getPriceDesignators(Map<String, Object>)
Gets the standard set of price designators
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=DataMappingValueDefinitionsLocal.MAPPED_NAME, methodName=DataMappingValueDefinitionsLocal.getPriceDesignators // ...
Methods defined in com.priint.pubserver.comet.bridge.value.CometValueDefinitionsLocal (CometBridgeSDK).
All of these methods require a connection to a Comet project.
getTemplates(Map<String, Object>)
Gets all templates of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getTemplates // ...
getBucketEntities(Map<String, Object>)
Gets all Bucket entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getBucketEntities // ...
getCordEntities(Map<String, Object>)
Gets all Cord entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getCordEntities // ...
getEntities(Map<String, Object>)
Gets all entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getEntities // ...
getKeyValueEntities(Map<String, Object>)
Gets all KeyValue entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getKeyValueEntities // ...
getMediaAssetEntities(Map<String, Object>)
Gets all MediaAsset entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getMediaAssetEntities // ...
getPlanningEntities(Map<String, Object>)
Gets all Planning entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getPlanningEntities // ...
getPriceEntities(Map<String, Object>)
Gets all Price entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getPriceEntities // ...
getTableDataEntities(Map<String, Object>)
Gets all TableData entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getTableDataEntities // ...
getTextEntities(Map<String, Object>)
Gets all Text entities of the entity model of the current Comet project
// ... value=@Value( type=Value.Type.PLUGIN, pluginMappedName=CometValueDefinitionsLocal.MAPPED_NAME, methodName=CometValueDefinitionsLocal.getTextEntities // ...
DataMapping Methods
For further information about the parameter meanings, refer to the SDK documentation
Methods defined in com.priint.pubserver.plugins.datamapping.DataMappingToString
textListToString
- Requested Records
- Delimiter
- Prefix
- Suffix
textListToStrings
- Delimiter
- Prefix
- Suffix
firstKeyValueToString
- Designator
firstKeyValueByKeyToString
- Key
- Designator
mapKeyValuesToString
- Requested Records
- Delimiter
- Prefix
- Suffix
- Designator
mapKeyValuesByKeyToString
- Requested Records
- Key
- Delimiter
- Prefix
- Suffix
- Designator
valuesByKeyToStrings
- Key
mediaAssetListToFileUrl
- Media type
- Media format
firstMediaAssetToFileUrl
- Media type
- Media format
lastMediaAssetToFileUrl
- Media type
- Media format
mediaAssetListToFilePath
- Media type
- Media format
firstMediaAssetToFilePath
- Media type
- Media format
lastMediaAssetToFilePath
- Media type
- Media format
priceListToString
- Requested Records
- Delimiter
- Prefix
- Suffix
- Designator
DataProcessing Methods
Methods defined in com.priint.pubserver.plugins.dataprocessing.StringFunctions
setPrefix
- Prefix
replace
- Search
- Replace
replaceRegEx
- Pattern
- Replace
truncate
- Maximum length
leftPad
- Fill character
- Truncate
rightPad
- Fill character
- Truncate
match
- Pattern
inverseMatch
- Pattern
substring
- Begin Index
- End Index
join
- Prefix
- Delimiter
- Suffix
- Minimum elements
split
- Prefix
- Delimiter
- Suffix
- Minimum elements
Methods defined in com.priint.pubserver.comet.bridge.CometElementFunctions
setTemplate
- Template