From version 4 onwards InDesign® Comet plug-ins support data connections with the priint PublishingServer. Some formerly project-specific requirements have become standard.
Good News: Apart from few exceptions, Comet 4 and the PublishingServer work just like before. More good news: Some things are far easier to realize.

An overview of new functions, changes and limitations:

In the PublishingServer environment, the StringID contains all relevant information to determine hierarchy and context. As a rule, the numeric IDs ID, ID2 and ID3 have therefore become obsolete (for reasons of validity, ID must not have the value 0, which is why it is always set to 1).

The StringID is structured in the following way (but without the only for better readability inserted line separators):

 recordId
#groupId
#entityId
#entityClass
#parentRecordId
#parentGroupId
#parentEntityId
#parentEntityClass

For explanations of the single elements, consult the PublishingServer documentation of the EntityManager/entity model.

In placeholder scripts, single components of the StringID can be accessed via the following tags, environment variables and/or cScript functions:

Tag Variable Function Description
<Record.Id> gPSRecordId idtype::record_id ID of the data record
<Record.GroupId> gPSGroupId idtype::group_id Group ID of the data record
<Entity.Id> gPSEntityId idtype::entity_id Identifier of the entity
<Entity.Class> gPSEntityClass idtype::entity_class Class of the entity
<Record.ParentId> gPSParentRecordId idtype::parent_record_id ID of the parent of data record
<Record.ParentGroupId> gPSParentGroupId idtype::parent_group_id Group ID of the parent data record
<Entity.ParentId> gPSParentEntityId idtype::parent_entity_id Identifier of the entity of the parent
<Entity.ParentClass> gPSParentEntityClass idtype::parent_entity_class Class of the entity of the parent

In TableInsert methods, the following tags and/or environment variables are defined:

Tag Variable Description
<RootTableRecord.Id>gPSRootTableRecordIdID of the data record of the table
<RootTableRecord.GroupId>gPSRootTableGroupIdGroup ID of the data record of the table
<RootTableEntity.Id>gPSRootTableEntityIdIdentifier of the entity of the table
<RootTableEntity.Class>gPSRootTableEntityClassClass of the entity of the table
<RootTableRecord.ParentId>gPSRootTableParentRecordIdID of the parent data record of the table
<RootTableRecord.ParentGroupId>gPSRootTableParentGroupIdGroup ID of the parent data record of the table
<RootTableEntity.ParentId>gPSRootTableParentEntityIdIdentifier of the entity of the parent of the table
<RootTableEntity.ParentClass>gPSRootTableParentEntityClassKClass of the entity of the parent of the table
<ColumnRecord.Id>gPSColumnRecordIdID of the data record of the column
<ColumnRecord.GroupId>gPSColumnGroupIdGroup ID of the data record of the column
<ColumnEntity.Id>gPSColumnEntityIdIdentifier of the entity of the column
<ColumnEntity.Class>gPSColumnEntityClassClass of the entity of the column
<ColumnRecord.ParentId>gPSColumnParentRecordIdID of the parent data record of the column
<ColumnRecord.ParentGroupId>gPSColumnParentGroupIdGroup ID of the parent data record of the column
<ColumnEntity.ParentId>gPSColumnParentEntityIdIdentifier of the entity of the parent of the column
<ColumnEntity.ParentClass>gPSColumnParentEntityClassClass of the entity of the parent of the column
<RowRecord.Id>gPSRowRecordIdID of the data record of the row
<RowRecord.GroupId>gPSRowGroupIdGroup ID of the data record of the row
<RowEntity.Id>gPSRowEntityIdIdentifier of the entity of the row
<RowEntity.Class>gPSRowEntityClassClass of the entity of the row
<RowRecord.ParentId>gPSRowParentRecordIdID of the parent data record of the row
<RowRecord.ParentGroupId>gPSRowParentGroupIdGroup ID of the parent data record of the row
<RowEntity.ParentId>gPSRowParentEntityIdIdentifier of the entity of the parent of the ro
<RowEntity.ParentClass>gPSRowParentEntityClassClass of the entity of the parent of the row
<CellRecord.Id>gPSCellRecordIdId of the data record of the cell
<CellRecord.GroupId>gPSCellGroupIdGroup Id of the data record of the cell
<CellEntity.Id>gPSCellEntityIdIdentifier of the entity of the cell
<CellEntity.Class>gPSCellEntityClassClass of the entity of the cell
<CellRecord.ParentId>gPSCellParentRecordIdID of the parent data record of the cell
<CellRecord.ParentGroupId>gPSCellParentGroupIdGroup ID of the parent data record of the cell
<CellEntity.ParentId>gPSCellParentEntityIdIdentifier of the entity of the parent of the cell
<CellEntity.ParentClass>gPSCellParentEntityClassClass of the entity of the parent of the cell

Moreover, two new tags are supported in all environments:

In order to modularize cscripts or reuse own cscript functions, script libraries can be created in priint:ison. Further information can be found in the priint:ison user manual.
A identifier is attached to these libraries, making it possible to integrate them into cscript:

 #include "[pubserver]/Identifier.h" 

Methods of your (server) Java plug-ins can be used via commands according to the following scheme:

#include "[pubserver]/plugin/Plugin-mapped-name.c"

Documented headers of functions available for a Java Plugin can be obtained with this include instruction (caution, this is for documentation only, this code cannot be interpreted by the cscript interpreter):

#include "[pubserver]/plugin/Plugin-mapped-name.h"

Methods of all available Plug-Ins can be obtained this way:

#include "[pubserver]/plugins.c"

Or, again, just the documented headers of all Plug-Ins:

#include "[pubserver]/plugins.h"

Finally the include directive for the CScriptStandardLibrary:

#include "[pubserver]/stdlib.c"
// Shortcut for:
#include "[pubserver]/plugin/com.priint.pubserver.comet.bridge.cscript.CScriptStandardLibrary.c" 

And the documented function signatures:

#include "[pubserver]/stdlib.h"
// Shortcut for:
#include "[pubserver]/plugin/com.priint.pubserver.comet.bridge.cscript.CScriptStandardLibrary.h"

For more information see section Calling up own Java plug-ins.

Several new cscript functions make sense especially in the PublishingServer environment and have been documented thoroughly in the respective module:

In the PublishingServer environment, placeholders are configured exclusively via priint:ison. Data access takes place via DataProviders (also configured in priint:ison).
For detailed information, see the PublishingServer documentation; here only a short introduction:
A DataProvider fulfills two tasks:

Complete implementations for both tasks come with the delivery of the PublishingServer; own methods, if desired, can be developed as Java plug-ins and added.
A placeholder can define methods for additional data preparation. Again, ready-for-use implementations are delivered and own methods can be provided as Java plug-ins.

As a result, implementing further data preparation through cscript should not be necessary (before such a decision, see Layout rules).
If it seems unavoidable nevertheless, the standard load method of the placeholder can be called up through the cscript function

server::load_placeholder_str 

For detailed documentation and examples, click here.

Example: Loading a placeholder
This script has no effect at all; it just loads the text via the access method that is configured on the server, including all conversions and adaptations, and finally inserts the text into the placeholder - which is the same one would expect without script.
In order to give it a certain meaning anyway, we write the text that we got from the server into the log file before:

int main ()
{
	String		str 		= string::alloc();
	int			result 		= server::load_placeholder_str(str);

	wtlog("", "load_placeholder_str result=%d, text='%s'\n", result, str);

	if (result == 0)
	{
		textmodel::replace(str);
	}

	string::release(str);
	return result;
}

Example 2: Overwriting parameters
Key value pairs can be set as third ... nth parameter. The names of PublishingServer-specific tags are useful keys, e. g. Record.Id, Entity.Id, Entity.ContextLanguage etc.
This makes it possible to "bend" placeholders and, for instance, specify a context (to be determined client-sidedly). Whether this makes sense and it would be better to configure an adequate context rule for the placeholder, is another story...

int main ()
{
	String 		str 	= string::alloc ();
	int			result 	= server::load_placeholder_str(
							str,
							"Entity.ContextLanguage", "eng",
							"Model.Id", "Anderes_Datenmodell");

	wtlog("", "load_placeholder_str result=%d, text='%s'\n", result, str);

	if (result == 0)
	{
		textmodel::replace(str);
	}

	string::release(str);
	return result;
}

These information apply to classical table building; besides, server-side building of tables is possible in the PublishingServer. Which option works best varies from case to case.
During client-side (classical) generation, it is deposited for columns, rows and single cells which method product or article IDs for the building of the table are determined with. These are the so-called TableInsert methods that can be set up via priint:ison, too.
The principle is similar to that of placeholders: Data are loaded via a DataProvider that additionally deals with the transformation into an adequate structure - there are two differences, however:

More information can be found here

In the seldom case that the IDs have to be determined in a separate cscript, you can access the standard load function of the TableInsert method like this:

server::load_table_ids(gProducts, gMoreGroups) 

For detailed documentation and examples see here.

Example: The simplest TableInsert script
This script behaves "neutral", meaning that the result would be the same if one directly executed the method configured for the column, row or cell:

int main ()
{
	return server::load_table_ids(gProducts, gMoreGroups);
}

Just like with the server::load_placeholder function, values can be overwritten through key value pairs as third .. nth parameter.

Please note
Using the server::dataprovider_load function is generally deprecated. The easier and more secure solution would be - dependeing on the calling context - In the script documentation you can find further information, why you should use one of these alternatives and why not to use server::dataprovider_load.

Similar to placeholders or tables, you can load (almost) arbitrary DataProviders in an arbitrary script environment. In this case, you have to enter all necessary values (normally adopted automatically from the placeholder or table context) manually (as key value pairs of the function "pass on as").
Please note:

For detailed documentation and examples see here.

 href="../../cscript/server.html#dataprovider_load">server::dataprovider_load() 

Example: Filling an IDTypeList

int main ()
{
	IDTypeList 	ids 	= idtypelist::alloc();
	int 		result 	= 0;
	int 		index  	= 0;
	
	result = server::dataprovider_load(ids, "ChildBuckets", 0, 0, "Record.Id", "<Record.Id>");
	if (result == 0)
	{
		// copy ids to the global IDTypeList gProducts (will only work this way, if executed as a TableInsert method)
		for (index = 0; index < linklist::length(ids); ++index)
		{
			idtypelist::insert(gProducts, -1, idtypelist::get(ids, index);
		}
	}
	// clear list, but do not clear entries
	idtypelist::clear(ids, 0);
	return result;
 }

Example: Getting a simple string

int main ()
{
	char 	* 	value 	= alloc(32768); 
	int 		result 	= 0;
	
	result = server::dataprovider_load(value, "FirstText", 0, 0, "Record.Id", "<Record.Id>", "Entity.ContextLanguage", "deu");
	if (result == 0) 
	{
		textmodel::replace(value);
	}
	release(value);
	return result;
}

This requires the installation of the Java server plug-in CometTableOfContents.
The plug-in provides special DataQuery methods which, in connection with an accordingly configured DataProvider and a text placeholder of the entity Table Of Contents, enable access to table-of-contents data in your InDesign® or PDF document. For configuration of the data access see the documentation of the priint-ison application.

Table-of-contents entries can be created by calling up the cscript function

linklist::insert_toc_entry()

Example: Creating table-of-contents entries of a a certain placeholder 

#include "internal/types.h"

int main ()
{
	LinkList 	placeholders = linklist::alloc(1);
	int 		result;
	
	linklist::insert(placeholders, 67301234);
	result = linklist::insert_toc_entry(placeholders, kDesignateDocument, "myPublication", "12345"); 
	linklist::release(placeholders);
	
	return result;
}

Java methods of a PubServer Plugin can be invoked in cscript. Some prerequisites must be fulfilled:

In return you gain smooth integration of Java functionality in cscript - at almost no cost.

Example 1 - Hello

The basic concept is best explained with this example (we expect basic knowledge in Java and cscript programming):

@Stateless(mappedName=HelloWorld.MAPPED_NAME)
@LocalBean
@PubServerPlugin
public class HelloWorld extends PluginControlDefault {
	
	public static final String MAPPED_NAME = "com.priint.pubserver.comet.cscript.HelloWorld";
	
	/**
	 * Hello World
	 * 
	 * @return Hello World
	 */
	@PubServerMethod(type=PluginMethod.MethodType.GENERIC)
	@CometCScriptFunction
	public String helloWorld() {
		return "Hello World";
	}
}   
the corresponding cscript code to call this function:
#include "[pubserver]/plugin/com.priint.pubserver.comet.cscript.HelloWorld.c"
     
int main()
{
    char 	* 	message = helloWorld();
    
    showmessage("Server said: %s", message);
    release(message);
    
    return 0;
}

Example 2 - Parameters

The second example shows, how to pass parameters to a method:

@Stateless(mappedName=HelloWorld.MAPPED_NAME)
@LocalBean
@PubServerPlugin
public class HelloWorld extends PluginControlDefault {
	
	public static final String MAPPED_NAME = "com.priint.pubserver.comet.cscript.HelloWorld";
	/**
	 * Hello World
	 * 
	 * @return Hello World
	 */
	@PubServerMethod(type=PluginMethod.MethodType.GENERIC)
	@CometCScriptFunction
	public String helloWorld2(@PubServerMethodParameter String login) {
		return "Hello " + login + "!";
	}
}   
The corresponding cscript code:
#include "[pubserver]/plugin/com.priint.pubserver.comet.cscript.HelloWorld.c"

int main()
{
    char 	* 	login   	= alloc(4096);
    char 	* 	message 	= 0;
    
    login   = system::login(login);
    message = helloWorld2(login);
    showmessage("Server said: %s", message);
    
    release(message);
    release(login);
    
    return 0;
}

Résumé:

and and

More basic information

 

The Java / Eclipse project DemoCScript delivered with the Ison workspace contains lots of more examples and information.

The cscript language and Java language - though similar regarding the syntax - differ in many aspects:

The @CometCScriptFunction allows to specify, whether the cscript stub for a Java method uses should be called as a function or as a proceddure, no matter, if the method returns a value or not. Use the attribute callStyle:

If you use CallStyle.PROCEDURE for a method, which actually returns a value, an additional out variable is inserted at the front of the cscript function parameterlist.(see 3d example below).

Example 1 - "function"

@Stateless(mappedName=HelloWorld.MAPPED_NAME)
@LocalBean
@PubServerPlugin
public class HelloWorld extends PluginControlDefault {

	@PubServerMethod(type=PluginMethod.MethodType.GENERIC)
	@CometCScriptFunction(callStyle=CallStyle.FUNCTION /* = default! */ )
	public int max(
			@PubServerMethodParameter(name="n1") int n1, 
			@PubServerMethodParameter(name="n2") int n2) {
		return n1 > n2 ? n1 : n2;
	}
}   
The corresponding cscript code:
// function signatur<
int max(int n1, int n2);

// example call
int n = max(17, 23);

Example 2 - "procedure"

@Stateless(mappedName=HelloWorld.MAPPED_NAME)
@LocalBean
@PubServerPlugin
public class HelloWorld extends PluginControlDefault {

	@PubServerMethod(type=PluginMethod.MethodType.GENERIC)
	@CometCScriptFunction(callStyle=CallStyle.PROCEDURE)
	public void sendEmail(
			@PubServerMethodParameter(name="recipient") String recipient) throws CometException {
		try {
		 	deliverEmail(recipient);
		}
		catch (Exception e) {
			int errorCode = 13;
			throw new CometException(errorCode, "Could not deliver Email, reason: " + e.getMessage(), e);
		}
	}
}   
The corresponding cscript code:
// function signature
int sendEmail(char* recipient);

// example call
int errorCode = sendEmail("support@priint.com");

Example 3 - "procedure with return value"

@Stateless(mappedName=HelloWorld.MAPPED_NAME)
@LocalBean
@PubServerPlugin
public class HelloWorld extends PluginControlDefault {

	@PubServerMethod(type=PluginMethod.MethodType.GENERIC)
	@CometCScriptFunction(callStyle=CallStyle.PROCEDURE)
	public String sendEmail(
			@PubServerMethodParameter(name="recipient") String recipient) throws CometException {
		try {
		 	deliverEmail(recipient);
			String status = getMailDeliveryStatus();
			return status;
		}
		catch (Exception e) {
			int errorCode = 13;
			throw new CometException(errorCode, "Could not deliver Email, reason: " + e.getMessage(), e);
		}
	}
}   
The corresponding cscript code
// function signature
// An additional parameter is inserted at the front of the  
// function parameter list (char** out), see explanations
// above.
int sendEmail(char** out, char* recipient);

// example call
char* status = 0;

// please note the address-operator, we pass the address of
// the string (char*) pointer. If call succeeds, status points
// to a valid char* address, otherwise status will remain null.
int errorCode = sendEmail(&status, "support@priint.com");

if (errorCode == 0) {
	wlog("", "Sending mail succeeded, current status: %s\n", status);
}
else {
	wlog("", "Sending mail failed with error code '%d'\n", errorCode);
}
if (status != 0) {
	release(status);
}

Example 4 - error handling using function style

Unless specified otherwise, the return value of a function on errors is

If another value should be returned in case of errors, you can use the failureValue attribute of the @CometCScriptFunction annotation.

Note:

@Stateless(mappedName=HelloWorld.MAPPED_NAME)
@LocalBean
@PubServerPlugin
public class HelloWorld extends PluginControlDefault {
	
	public static final String MAPPED_NAME = "com.priint.pubserver.comet.cscript.HelloWorld";
	/**
	 * Hello World
	 * 
	 * @return Hello World
	 */
	@PubServerMethod(type=PluginMethod.MethodType.GENERIC)
	@CometCScriptFunction(failureValue="You are not welcome. Goodbye.")
	public String helloWorld3(@PubServerMethodParameter String login) throws PubServerException {
		if (login.equals("me")) {
		    return "Hello " + login + "!";
		} 
		else {
			throw new AuthenticationFailureException();
		}
	}
}   
Corresponding cscript code:
#include "[pubserver]/plugin/com.priint.pubserver.comet.cscript.HelloWorld.c"

int main()
{
    char 	* 	login   	= alloc(4096);
    char 	* 	message 	= 0;
    int 		result   	= 0;
    
    login   	= system::login(login);
    message 	= helloWorld3(login);

    // in real life you chould check for null
    if (strcmp(message, "You are not welcome. Goodbye.") == 0) 
    {
		showmessage("Hello world failed: %s", message);
		result = 1;
    }
    
    release(message);
    release(login);
    
    return result;
}

The Java / cscript interface supports the types listed below as parameter or return types.

General directives in cscript:

Some examples:
// valid:
WorkflowStatus 	status = 0;
status = getStatusOfPublication("67110123");
publication::workflowstatus::release(status);

// invalid:
WorkflowStatus status = publication::workflowstatus::alloc();
status = getStatusOfPublication("67110123");
publication::workflowstatus::release(status);
// Why? The memory formerly allocated for status is not 
//      referenced any more and therefore can no more be released.

// valid, but dubious:
WorkflowStatus status = publication::workflowstatus::alloc();
publication::workflowstatus::release(status);
status = getStatusOfPublication("67110123");
publication::workflowstatus::release(status);

// valid, but dubious:
char * publicationId = "67110123";
publicationId = findParentPublication(publicationId);
release(publicationId);

// wrong!
int n = getMax(17, 23);
release(n);
Note for Java developers: all Comet data types supported can be found in the CometBridgeSDK, package com.priint.pubserver.comet.bridge.entitydata. In the following table, we use the shortcut c.p.p.c.b.e for this package.

Classes of the EntityManager / EntityModel (Bucket, Text, KeyValue, MediaAsset etc.) cannot be used directly, they first must be transformed into a suitable Comet data type. The CometBridgeSDK provides various utility classes and methods for data mapping, id parsing and mapping etc.
Java Type CScript Type CScript Type (out) Remarks
void, Void int - There is no void equivalent in cscript, the int return type can just be ignored.
boolean, Boolean int int* Possible loss of data
byte, Byte int int* Possible loss of data
short, Short int int* Possible loss of data
int, Integer int int*  
long, Long int int*  
BigDecimal int int* Possible loss of data
BigInteger int int* Possible loss of data
float, Float float float*  
double, Double float float*  
String char* char**

For the cscript result variable no memory must be allocated, the but the variable must be released:

Release:
  release(str);

c.p.p.c.b.e.RecordId IDType IDType*

Release:
  idtype::release(id);

c.p.p.c.b.e.Parameter Parameter Parameter*

Release:
  publication::parameter::release(param);

c.p.p.c.b.e.Product Product Product*

Release:
  product::release(p);

c.p.p.c.b.e.Publication Publication Publication*

Release:
  publication::release(pub);

c.p.p.c.b.e.PublicationType PublicationType PublicationType*

Release  publication::publication::release(pubType);

c.p.p.c.b.e.WorkflowStatus WorkflowStatus WorkflowStatus*

Release:
  publication::workflowstatus::release(status);

java.util.List<Boolean> List List*

Possible loss of data

Release:
  list::release(intList);

java.util.List<Byte> List List*

Possible loss of data

Release:
  list::release(intList);

java.util.List<Short> List List*

Possible loss of data

Release:
  list::release(intList);

java.util.List<Integer> List List*

Release:
  list::release(intList);

java.util.List<Long> List List*

Release:
  list::release(intList);

java.util.List<BigDecimal> List List*

Possible loss of data

Release:
  list::release(intList);

java.util.List<BigInteger> List List*

Possible loss of data

Release:
  list::release(intList);

java.util.List<Float> FloatList FloatList*

Release:
  floatlist::release(floats);

java.util.List<Double> FloatList FloatList*

Release:
  floatlist::release(floats);

java.util.List<String> StringList StringList*

Release:
  stringlist::release(strings);

java.util.List<c.p.p.c.b.e.RecordId> IDTypeList IDTypeList*

Release:
  idtypelist::release(ids);

java.util.List<c.p.p.c.b.e.Parameter> ParameterList ParameterList*

Release:
  publication::parameterlist::release(params);

java.util.List<c.p.p.c.b.e.Product> ProductList ProductList*

Release:
  productlist::release(products);

java.util.List<c.p.p.c.b.e.Publication> PublicationList PublicationList*

Release:
  publication::publicationlist::release(pubs);

java.util.List<c.p.p.c.b.e.PublicationType> PublicationTypeList PublicationTypeList*

Release:
  publication::publicationtypelist::release(pubTypes);

java.util.List<c.p.p.c.b.e.WorkflowStatus> WorkflowStatusList WorkflowStatusList*

Release:
  publication::workflowstatuslist::release(states);

The @PubServerMethod, @CometCScriptFunction and @PubServerMethodParameter annotations allow detailed documentation of the Java methods and corresponding cscript functions.
At the time (Version 4.0.5) there is no support for this in the Ison editor, so cscript developers must derive all information from the Java classes and methods - or download generated headers with documentation using a suitable tool.

You can use the Placeholder Options panel in InDesogn Desktop (this requires a developer license for the comet Plugins):

Enter a File ID in the Script ID / File ID field and click the disk symbol to download this file.

Start with File-ID [pubserver]/plugins.c, this will list all available includes, Example::

#include "[pubserver]/plugin/com.priint.pubserver.comet.cscript.HelloWorld.c"
#include "[pubserver]/plugin/com.priint.pubserver.comet.cscript.PrimitiveTypes.c"
#include "[pubserver]/plugin/com.priint.pubserver.comet.bridge.cscript.CScriptStandardLibrary.c" 

Now you can repeat this procedure for any include of interest.

Alternatively you can download [pubserver]/plugins.h , this will show all function signatures including inline documentation:

/**
 * <p>sophisticated hello world example</p>
 * <p>
 *   This is a more sophisticated hello world example.
 *   
 *   The PubServerMethod label and description are used for cscript inline
 *   documentation.
 *   Try downloading
 *     [pubserver]/plugin/com.priint.pubserver.comet.cscript.HelloWorld.h
 *   from your client application (e.g. InDesign® Desktop), to see the effect.
 *   The following cscript code calls this method:
 *   <pre>
 *     #include "[pubserver]/plugin/com.priint.pubserver.comet.cscript.HelloWorld.c"
 *     int main() {
 *       char * login = alloc(4096);
 *       char * hello = helloWorld3(system::login(login));
 *       showmessage("Server said: %s", hello);
 *       release(hello);
 *       release(login);
 *       return 0;
 *     }
 *   </pre>
 * </p>
 * @return char*
 * @param char* login user login on the client host
 */
char* helloWorld(char* login);
...
This works for all Plugins or for a particular Plugin, e.g..
[pubserver]/plugin/com.priint.pubserver.comet.cscript.HelloWorld.c

 


Question

Can I define only one cscript / Java method per Plugin?

Answer

Of course not, you can define an arbitrary number of methods. The more methods, the larger the generated cscript stub code will be, therefore you should not define too much methods in one Plugin.
There is a second reason, why too many methods in one Plugin could cause problems: function names must be unique in cscript. It is not possible to overload functions in cscript.

The resulting limitations apply for methods in one Plugin and also for methods in all Plugins, that potentially are included in one cscript at the same time: if Plugin A contains a function named foo and Plugin B contains a function named foo also, they cannot be included in one cscript at the same time.


Question

Can I propagate existing Java methods as cscript functions?

Answer

Yes, if your method is part of a PubServerPlugin and if you respect the limitations regarding supported types mentioned above. In this case, all you have to do is add the @CometCScriptFunction annotation to your method..


Question

What about performance?

Answer

When invoking Java methods from cscript, the following happens: cscript objects and values are serialized to XML, the XML is sent to the PubServer via SOAP, the server unpacks the SOAP message and parameter XML and invokes the Java Plugin. The call result is again transformed in XML, sent back to InDesign® via SOAP, unpacked, unserialized and assigned to the cscript result variables. Sounds like much effort and costs.

Typically a roundtrip (without any calculatino done on the server) should take about 30ms. This is an acceptable overhead for complex operations, but far too much for simple calculations (such as strcmp, strcat ...), which can easily and much more efficient be implemented in cscript.


Question

Why is the char resp. Character type not supported?

Answer

There is no suitable corresponding XML Schema builtin type for single characters. But more important: single characters could be misinterpreted, because strings in cscript are utf-8 encoded. This means, a visible character can consist of several character bytes. All cscript string functions respect this: the length returned by strlen is the number of visible characters, not of character bytes; any string position in any function refers to visible characters (not bytes).


Question

What is the maximum length for Strings returned from Java methods?

Answer

Virtually infinite. The memory is allocated dynamically.


Question

Is the number and size of parameters limited?

Answer

No - at least not regarding translations and transport.


Questions

Are tags (such as <Record.Id> ...) supported in scripts, which include Java methods?

Answer

Java methods can be included in any cscript: placeholder scripte, panel scripts, layout rules, build scripts etc.
Which tags and global variables are available, depends on the call environment, there are no exceptions for scripts including Java methods.


Question

Can I access document poperties from Java?

Answer

Only those passed as parameter. The communication is unidirectional, you cannot callback InDesign® from the Java Plugin. Therefore it's neither possible to access document frame properties nor to manipulate page items from your Java Plugin.


Question

We were talking about InDesign®, is the cscript / Java bridge supported in the PDF Renderer too?

Answer

yes, of course.