Unable to apply ColdFusion 11 Update 1

Recently ColdFusion 11 update 1 was out and blogged here.
The technote
lists the bug fixes included in this specific update.

In case you are unable to apply the update directly from the
ColdFusion Admin, here are some tweaks you can try:-

Start ColdFusion from
command line and apply the update

  1. Stop ColdFusion service or ‘ColdFusion 11 Application Server’
    service.
  2. Launch command prompt with “Run as Administrator” feature.
  3. Navigate to ColdFusion11cfusionbin
  4. Type cfstart.bat and hit enter.

Once the server startup message appears on the prompt,
navigate to ColdFusion Admin and apply the update.

Apply the update manually

Download the hotfix from here
and then you can follow the instructions
to apply the update.

Apply the “Service
startup fix” first and then update 1

  1. In case the above two suggestions doesn’t work, then first apply
    the service startup hotfix hf1100-3776060 and then Update 1.
  2. Download the hotfix from hf1100-3776060.jar
  3. Place this hotfix at ColdFusion11cfusionlibupdates
  4. Restart the ‘ColdFusion 11 Application Service’.
  5. Navigate to ColdFusion Admin and apply the update.

Note: The above cases are based upon user scenarios/environments.
All the other updates should be applied via the ColdFusion Administrator
directly.

ColdFusion 11 Update 1 now available

The first update for ColdFusion 11 is now available to you for install from within the administrator via the update mechanism.

Here is the link for the associate technote which details out the important issues fixed.

EDIT: There is an upcoming update (post update 1) that has more than 100+ bugs fixed for CF10 and CF11 along with updated platform support for recent releases of OS, Application Servers, Java 8 and Databases. The intent of this first update was to release some of the critical issues blocking CF11 use sooner than making it a part of the larger upcoming update.

ColdFusion 11 IIS Connector Tuning

Connector tuning is an essential part of setting up a ColdFusion server. There are various configurations in connector that needs to be tuned. Incorrect values may lead to “Service Unavailable” or “Server too busy”. In this blog, we will discuss how to handle such errors caused by incorrect tuning and how to tune the connectors for the site correctly.

The connector setting may vary from site to site. It is very important to configure the connectors for your application appropriately. This blog will include connector tuning parameters for IIS. During installation, user can choose to configure connector for “Individual Site” or “ALL” sites in IIS connector configuration.

Configure Web Server

After the installation, the user can launch the “Web Server Configuration tool” and has the availability to create the connector for “Individual Site” or “ALL” sites in IIS.

Add Web Server configuration

When connector is configured with individual sites, separate connector for each site will be placed under {CF-Home}/config/wsconfig/{some no}/. Similarly for “ALL” configuration the connector is configured at global level, which means the same connector binary will be used across multiple sites.

The three most important parameters will be discussed here and will help us to understand the role of the same:-

  • Reuse Connections
  • Connection pool size
  • Connection pool timeout

Re-use connections: – This setting determines the count of connections that can be re-used. When Tomcat connector makes a connection with Tomcat server, it does not closes the connection even after it finished serving the request. Instead it keeps the connection active, so that for the next request, the same connection can be re-used. This increases the performance by minimizing the overhead of creating new connection with tomcat server for every request. This settings needs to be tuned for connector configured with multiple sites. The max value for the re-use connection is determined based on the number of sites configured with same CF server and the load on each site.

The default re-use connection is 250.

Connection pool size: – This setting determines the maximum number of connections that can be created in the connection pool. When multiple requests arrive to the connector from IIS, connector creates new connections in the connection pool only if there are no free connections available in the pool. The connector will not create a new connection if connections reach the connection pool size limit. When connector is configured with “ALL” sites, the same connection pool will be used to serve the request for all sites. So the default value of the connection pool size, works well with the single site configuration, but fails to work well with “ALL” site configuration in some scenarios. Hence this value should be increased carefully based on the need and number of sites that are present within IIS.

The default connection pool size is same as, which is 250.

Connection pool timeout: – This setting determines the timeout value (in seconds) for idle connections in connection pool. This value must be in sync with the connectionTimeout attribute of your AJP connector in Tomcat's server.xml.

The default timeout for connection is indefinite, if not set in server.xml explicitly.

There are other parameters which CF connector inherits from Tomcat AJP connector. Please find the details of those settings from AJP documentation (http://tomcat.apache.org/connectors-doc/reference/workers.html)

The worker.properties is available at {CF-Home}/config/wsconfig/{some no}/ and the server.xml can be found at {CF-Home}/cfusion/runtime/conf/. Below are the changes required to tune the Site:-

  • Open the worker.properties file, add below line as new entry worker.cfusion.connection_pool_size=500 (This is connection pool size inside connector which are available to handle request)
  • Tune the entry for max_reuse_connections to appropriate value based on number of site. Optimal value is connection_pool_size / {no of site}
  •  Add another entry in new line worker.cfusion.connection_pool_timeout=60 (This value is idle connection timeout (in seconds), when sites are not under load connections will be recycled back to IIS)
  • Now open the server.xml from {cf-home/cfusion/runtime/conf}, add/update the maxThreads=500 and connectionTimeout="60000" to connection node containing the AJP entry.
    <Connector port="8012" protocol="AJP/1.3" redirectPort="8445" tomcatAuthentication="false"/>

  • Now the AJP entry in server.xml should look like 
    <Connector port="8012" protocol="AJP/1.3" redirectPort="8445" tomcatAuthentication="false" maxThreads="500" connectionTimeout ="60000"> </Connector>

 

 

 

There can be multiple use cases. Let us consider three most widely used scenarios:-

  •  Connector created with “ALL” OR with “Individual” Site and single site in IIS
  • Connector created with “ALL” and multiple sites in IIS
  • Connector created with “Individual” site and multiple sites site in IIS

 

 

Use Case# 1: Connector created with “ALL” OR with “Individual” Site and single site in IIS

In an idle scenario, where the user has only one site (configured with ALL or individual connector) and not running under high load, the worker.properties, can look like this

worker.list=cfusion

worker.cfusion.type=ajp13

worker.cfusion.host=localhost

worker.cfusion.port=8012

worker.cfusion.max_reuse_connections=250

worker.cfusion.connection_pool_size=500

worker.cfusion.connection_pool_timeout=60

And server.xml should look like

<Connector port="8012" protocol="AJP/1.3" redirectPort="8445" tomcatAuthentication="false" maxThreads="500" connectionTimeout ="60000"> </Connector>

So, we added the connection_pool_size and connection_pool_timeout (in seconds) in the worker.properties. The corresponding connectionTimeout (in milliseconds) is added to server.xml along with maxThreads whose value is equivalent to the connection_pool_size in the worker.properties.

Use Case# 2: Connector created with “ALL” and multiple sites in IIS

Consider a scenario that the connector is created with “ALL” and there is only one site which is running under load. The default 250 re-use connections are utilized by site 1. Later on, the user adds another site in IIS.

Site 1 will make all 250 re-usable connections with ColdFusion and any request for new connection from site 2 will be ignored by ColdFusion. Hence it is required, to increase the re-use connection count to optimal value, so that site 2 does not starve for new connections. This can be achieved by configuring optimal value of max_reuse_connections count. Considering that the site 2 is not running under high load, 100 re-use connection will work. So the max_reuse_connections becomes 350 {250 (for site 1) + 100 (for site 2)}. But, it is a good practice, to start tuning the connection_pool_size first, and then the max_reuse_connections appropriately.

This case would require connection_pool_size=700, as max_reuse_connections= connection_pool_size / {no of site}. So, the worker.properties will look like this

worker.list=cfusion

worker.cfusion.type=ajp13

worker.cfusion.host=localhost

worker.cfusion.port=8012

worker.cfusion.max_reuse_connections=350

worker.cfusion.connection_pool_size=600

worker.cfusion.connection_pool_timeout=60

And server.xml should look like

<Connector port="8012" protocol="AJP/1.3" redirectPort="8445" tomcatAuthentication="false" maxThreads="700" connectionTimeout ="60000"> </Connector>

Note: The connectionTimeout is in milliseconds

Use Case# 3: Connector created with “Individual” site and multiple sites site in IIS

Consider a scenario that the individual connectors are created for each site. There are three sites – Site 1 is running under high load, site 2 and site 3 running are under low load. For all the sites, there are individual connectors. Now, ideally in this scenario, we should start tuning with the site running under high load first. We can disable the timeout for high traffic sites, if we are not sure for timeout. If not defined, the default timeout for connection is indefinite. To start with, don’t specify the re-use parameter. Set the connection_pool_size=500 and monitor the site. Gradually increase the value by 100 and likewise, till the site is stable. Say, at connection_pool_size=800, the site is stable. Now, set the max_reuse_connections=270 (connection_pool_size / {no of site} i.e. 800/3=270 approx)

Site 1

worker.list=cfusion

worker.cfusion.type=ajp13

worker.cfusion.host=localhost

worker.cfusion.port=8012

worker.cfusion.max_reuse_connections=270

worker.cfusion.connection_pool_size=800

worker.cfusion.connection_pool_timeout=60

Site 2 and site 3 are running under low traffic, but are bind to same ColdFusion instance (cfusion in this case). The below settings should be optimal:-

Site 2

worker.list=cfusion

worker.cfusion.type=ajp13

worker.cfusion.host=localhost

worker.cfusion.port=8012

worker.cfusion.max_reuse_connections=100

worker.cfusion.connection_pool_size=250

worker.cfusion.connection_pool_timeout=60

Site 3

worker.list=cfusion

worker.cfusion.type=ajp13

worker.cfusion.host=localhost

worker.cfusion.port=8012

worker.cfusion.max_reuse_connections=100

worker.cfusion.connection_pool_size=250

worker.cfusion.connection_pool_timeout=60

And server.xml should look like

<Connector port="8012" protocol="AJP/1.3" redirectPort="8445" tomcatAuthentication="false" maxThreads="1300" connectionTimeout ="60000"> </Connector>

Note: The connectionTimeout is in milliseconds and the maxThreads is the value equivalent to summation of all the connection_pool_size(s). So, in this case maxThreads=1300 {800 (for site 1) + 250 (for site 2) + 250 (for site 3)}.

Some key points to remember:-

  • The connector tool should always run with “Run as Administrator” feature, even if the user is from the Administrator group i.e.

    Using the command line:-

    Connector Tool cmd

    Using the GUI

    Connector Tool gui
     

  • Any changes made to {CF-Home}/config/wsconfig/{some no}/, including isapi_redirect.dll or worker.properties, would require an IIS restart.
  • Any changes made to {CF-Home}/cfusion/runtime/conf/server.xml requires “ColdFusion 11 Application Server” service restart.
  • max_reuse_connections should always be less than or equivalent to connection_pool_size. It can’t be larger than the connection_pool_size.
  • The above use cases are scenario based and may vary from site to site, depending upon the load, architecture and traffic on the site.

Security Enhancements in ColdFusion Splendor – PBKDF2 and AntiSamy

ColdFusion 11 added few more security functions to the rich set of coldfusion security functions. Some of them includes protection against XSS using AntiSamy framework, PBKDF2 key derivation etc. In this blog post we will introduce you to the Antisamy and PBKDF2 key derivation functions added in coldfusion Splendor.

AntiSamy Support:

If there is a need to accept HTML/CSS input from the user then there is high possibility that the input containing XSS. In this case We can not use encoding functions as the HTML/CSS as the input need to be rendered by the browser. AntiSamy API provides an input validation technique which helps programmer to verify user-driven HTML/CSS input markup using a whitelist policy to ensure the input does not contain XSS. Antisamy validates using a policy file in which we can specify which HTML tags, attributes, css properties are allowed in the given input. The policy gives us more control on input validation/sanitization by providing directives,  regular expressions, rules for htmt tags and css properties . AntiSamy provides some example policy files which can be downloaded from here. They can be modified to suit your own project requirements. Check AntiSamy developer guide to know more about policy files.

Two new functions isSafeHTML and getSafeHTML were added which validates and cleans the given unsafe html as per the given policy.

isSafeHTML can be used to know whether the given input markup is in accordance with the rules specified in the antisamy policy. Returns true if valid else false if any violations are found.

getSafeHTML sanitizes the given input based on the the rules specified in an antisamy policy file. Returns cleanHTML string by cleaning the input against the defined policy.

The function syntax as below:

getSafeHTML(input [, PolicyFile ], throwOnError])
isSafeHTML(input [, PolicyFile ])
where

input
     
The HTML input markup text to sanitize/validate.

PolicyFile (Optional)
     Specify the path to the AntiSamy policy file. Given path can be an absolute path or a relative to the Application.cfc/cfc.Given path can be an absolute path or a relative to the Application.cfc/cfc.In case if not specified, there is a provision to set this at application level. Else the default policy file shipped with ColdFusion will be used. Default policy antisamybasic.xml can be found in the lib directory.

throwOnError (Optional)
      If set to true and given input violates the allowed HTML rules specified in the policy file an exception will be thrown. The exception message contains the list of violations raised because of the input. If set to false ignores the exception returns the HTML content filtered, cleaned according to the policy rules. Defaults to false.

Policy file can be set at application level using the key this.security.antisamypolicy in Application.cfc. The value must be an absolute path to the policy file or relative to the Application.cfc/cfm.

<cfcomponent>
<cfset this.security.antisamypolicy = "antisamy.xml">
</cfcomponent>

Here is a simple example which uses antisamy-tinymce.xml policy which allows many text formatting tags ,simple css properties and disallows javascript.

<!--- I am just using static input in this example when using this replace it with the relevant form parameter --->
<cfset unsafeHTML = "<script>alert('lorem ipsum lorem ipsum');</script><b>lorem ipsum lorem ipsum</b>">
<cfset isSafe = isSafeHTML(unsafeHTML)>
<cfset SafeHTML = getSafeHTML(unsafeHTML , "", false)>
 
<!--- returns No and provides the clean html as <b>lorem ipsum lorem ipsum</b> removes script from input  --->
<cfoutput> is Safe : #isSafe# Safe HTML : #SafeHTML# </cfoutput>
<cftry>
    <cfset SafeHTML = getSafeHTML(unsafeHTML , "", true)>
<cfcatch type="Application">
<!--- if throwOnError is true get the erros as specified below --->
<cfoutput>
    Errors in the input: <br/> #cfcatch.detail#
</cfoutput>
</cfcatch>
</cftry>

More detailed information and examples on antisamy can be found from here.

PBKDF2 Key Derivation:

PBKDF2 (Password based key derivation function) is a key derivation function which can be used to derive a cryptographic random key of desired key size from the humany-manageable passwords. PBKDF2 is widely used for generating random cryptography keys which can be used as key to encryption and HMAC algorithms. The function syntax as below

GeneratePBKDFKey(algorithm, inputString, salt, iterations, keysize)

algorithm
The encryption algorithm used to generate the encryption key. Supported algorithms are PBKDF2WithHmacSHA1, PBKDF2WithSHA1, PBKDF2WithSHA224,  PBKDF2WithSHA256,PBKDF2WithSHA384, PBKDF2WithSHA512.

inputString
Specify the input string (password/pass-phrase) which will be used for deriving the encryption key.

salt
Random cryptographic salt. Recommended length is 64 bits (8 characters) and must be randomly generated using a pseudo random number generator.

iterations
Desired Number of Iterations to perform the cryptographic operation. The minimum recommended number of iterations is 1000.

keySize
Desired arbitrary key length size in bits.

Below example shows how to derive a 192 bit encryption key from the given password. Then we are using key to encrypt and decrypt the data using AES algorithm. No need to store the encryption key as it will be derived from the password.

salt="A41n9t0Q";
        <!--- hard coding the password but in real password should be from some form parameter ---> 
	password = "Password@123";
	PBKDFalgorithm = "PBKDF2WithSHA224";
	dataToEncrypt= "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua";
	encryptionAlgorithm = "AES";
	derivedKey = GeneratePBKDFKey(PBKDFalgorithm ,password ,salt,4096,192);
	writeOutput("Generated PBKDFKey (Base 64) : " & derivedKey);
	encryptedData = encrypt(dataToEncrypt, derivedKey, encryptionAlgorithm, "BASE64");
	writeoutput("Data After Encryption: " & encryptedData);

        
	salt="A41n9t0Q";
	password = "Password@123";
	PBEalgorithm = "PBKDF2WithSHA224";
	derivedKey = GeneratePBKDFKey(PBKDFalgorithm ,password ,salt,4096,192);
	decryptedData = decrypt(encryptedData, derivedKey, encryptionAlgorithm, "BASE64");
	writeoutput("Data After Decryption: " & decryptedData);

More information and examples on PBKDF2 can be found from here.

Language Enhancements in ColdFusion Splendor – CF Functions for Query tag

Continuing the blog posts series on language enhancements, today, I am going to cover the Query functions and explain its various overloaded methods in detail. Before I discuss this feature, here is the list of language features added in ColdFusion Splendor.

Script syntax for Query tag is available in Splendor through the generic “Script support for tags“. This generic solution works well for all the other tags except CFQuery. CFQuery, being a bit complex, necessitated a need to provide an easy to use script-syntax for query execution. So, to simplify it in a script block, the query functions have been added in Splendor. These are designed in-line with existing ORM execute functions. The general syntax of query functions are:
QueryExecute(sql_statement);
QueryExecute(sql_statement, queryParams);
QueryExecute(sql_statement, queryParams, queryOptions);


As shown above, query functions can be invoked by passing one, two, or three parameters. The first parameter, an SQL statement is mandatory and the other two (queryParams and queryOptions) are optional. 

Query params:

There are two different ways to pass a parameter to an SQL query: named and positional (unnamed). In named parameter, you use “:” as the placeholder and pass a struct to queryParam. For the positional one, “?” is used as the placeholder and the values of the parameters are passed as an array to queryParams. 

  //named parameter 
  QueryExecute("select * from Employee where country=:country and artistid=:id", {country='USA', id:1});
  
  // positional parameter
  QueryExecute("select * from Employee where country=:? and artistid=?", ['USA', 1]);

If required, the CFQueryParam attributes information can also be passed for executing a query. For this, the attributes of an individual queryParam are first defined in a struct and then this struct is passed, rather passing  a simple string or number, as a  value of that param. To understand it better, an example is shown below:

//queryparams with attributes
QueryExecute("select * from Employee where country=:country and empId=id, {id:101, country:{name="USA", CFSQLType='CF_SQL_CLOB', list=true }});

QueryOptions

QueryOptions is a struct which contains different attribute values of a Query tag. In the following example, a “datasource” attribute has been passed in the queryOptions parameter. Similarly, all the attributes (except name) can be passed to queryOptions before executing a query.

 QueryExecute("select * from Artists where artistid=:id", {id:1},{datasource= "cfartgallery"});


This feature has been covered in details in Splendor document. See the doc for more information.

ColdFusion Splendor Public Beta E-seminar Series

We have a series of e-seminars lined up that gives you a good understanding of the various features of ColdFusion Splendor, which is now in public beta. If you haven’t downloaded ColdFusion Splendor already, here is the link where you download the public beta.

Here are the list of e-seminars:

1. Title- Public Beta E-seminar: ColdFusion Splendor Overview Date: 1st April Time: 8 am pacific. Find the recording for the e-seminar here

2. Title- Public Beta E-seminar: Everything about Mobile Application Development Date: 10th April Time 8 am pacific. Find the recording for the e-seminar here

3. Title- Public Beta E-seminar: Delicious Language Enhancements in ColdFusion Splendor Date: 12nd April Time 8 am pacific. Find the recording for the e-seminar here 

4. Title- Public Beta E-seminar: Pixel Perfect PDFs in ColdFusion Splendor Date: 24th April Time 8 am pacific. Find the recording for the e-seminar here

 

 

 

Language Enhancements in ColdFusion Splendor – Improved JSON serialization 2

In the previous post, I blogged about JSON serialization enhancements and covered a couple of
features around it. This post, a continuation from the last one, will cover the remaining features added in ColdFusion Splendor to serialize a ColdFusion object better. Before going into the details of the remaining improvements, here is the complete list of JSON features.

  • Data type preservation for Query and CFC 
  • Case preservation of struct keys
  • Added “Struct” as new QueryFormat
  • Custom serializer

Added “Struct” as new QueryFormat

In ColdFusion, Row and column are the supported types to serialize a query object. However, none of these two formats are fit for the jQuery type JavaScript framework. These JavaScript frameworks work well with column-value (like struct) format and to facilitate easy integration with these frameworks, a new query format “struct” has been introduced in ColdFusion Splendor. So, starting from Splendor, 3 different format types rowcolumn, and struct are now supported to serialize a query object to a JSON string. For example, to serialize a query object with 3 rows and 2 columns (colour,id), the serialized JSON string for row and struct query format will look like:

row  format:   {“ROWCOUNT”:3, “COLUMNS”:[“COLOUR”, “ID”], DATA:{“colour”: [“red”, “green”, “blue”], “id”: [1,2,3]}}

struct format:  [{“colour”:”red”, “id”:1}, {“colour”:”green”, “id”:2}, {“colour”:”blue”, “id”:3}]

As you can notice, the struct format is based on the key-value pair and is quite simple. The only downside of this format is the repetition of the column names. Here, the column names are repeated for each and every row.

Custom serializer

ColdFusion Splendor has enhanced JSON serialization support to help you hook your own custom serializer for serializing a ColdFusion object. The custom serializer enables you to register your own handler for serializing and deserializing the complex object. If the serializer is not specified, ColdFusion will use the in-built serialization handler.

Steps to use the custom serializer: There are two steps involved to hook a custom serializer in ColdFusion.

 1. Implement the custom serializer:  The customSerializer handler, a CFC, has four functions for you to implement.

  1. canSerialize
  2. serialize
  3. canDeserialize
  4. deserialize
 2. Register the handler:  Handler needs to be registered by adding its entry to application.cfc as following:
Application.cfc
<cfset this.customSerializer="MyCustomSerializer" />

This custom serializer has been explained in great details in ColdFusion Documentation

 

Language Enhancements in ColdFusion Splendor – Improved JSON serialization

I started a series of blog posts on language enhancements and so far covered Script support for tags and Member functions. Today, I will be blogging about the new features added in ColdFusion Splendor to improve JSON serialization.
Before I dive into the details of JSON serialization enhancements, here is the
list of the language features:

JSON serialization was first introduced in ColdFusion 8 and we constantly worked on improving this feature continously over the past several ColdFusion versions.

The complete list of JSON-level enhancements added to ColdFusion Splendor are:

  1. Data type preservation for Query and CFC 
  2. Case preservation of struct keys
  3. Added “Struct” as new QueryFormat
  4. Custom serializer
Data type preservation for Query and CFC
It has always been a challenge to rightly identify the underlying data type of a CFC property or of a column data of a query object. Prior to Splendor, ColdFusion used to check whether a data type can be converted to a number or boolean. If it can be converted, ColdFusion will automatically convert the property value to number/boolean irrespective of whether the property values needs conversion. Starting from Splendor, the metadata of the query, retrieved from the underlying database, will be used to identify the right data type of a column and the column data will be serialized based on that. Similarly, for a CFC, the CFC metadata will be retrieved and used to detect the right data type of the CFC property to serialize into.
Entity.cfc
 <cfcomponent persistent="true" table="partners" ... >
     <cfproperty name='zipcode' type="string" />
</cfcomponent>
index.cfm
   <cfscript>
        t = createObject("component", "Entity");
        t.setData("01003");
        writeoutput(serializeJSON(t));
   </cfscript>  


CF10 output      : {“zipcode”: 1003}
Splendor output : {“zipcode”: “01003”}

In the above example, unlike in ColdFusion10, the zipcode value is serialized as a string  and not as a number. Though the value looks like a numeric one, it will not be serialized as a number rather the data type information is retrieved from the underlying CFC metadata and  will be used to serialize it. 

Case preservation of struct keys

Prior to Splendor, ColdFusion did not preserve the case of a struct key but it converted it to the uppercase. Starting from Splendor, ColdFusion will preserve the original case of the struct key in which it is defined. But in case if you want to go back to the old ColdFusion behavior, you can use either the application setting or ColdFusion Administrator setting to switch back to the old behavior.  The following code will help you understand how this behavior works in ColdFusion10 and now:

<cfscript>
   data = {};
   data.empName ="John";
   data.age = 21;
   writeoutput(serialize(data));
</cfscript> 

Output in ColdFusion10   : {‘EMPNAME’= ‘John’, ‘AGE’=21}
Output in Splendor          :  {’empName ‘= ‘John’, ‘age’=21}

To keep this post short, I will be blogging the remaining JSON features in a separate post. Please refer the ColdFusion Splender public beta documentation for more details on JSON enhancement.   


Language Enhancements in ColdFusion Splendor – Member functions

Download the public beta of ColdFusion Splendor from here

I started a series of blog posts on language enhancements and covered “Script support for tags last week. Continuing on this, today I am going to blog about “Member function” that I hope should interest most of you. Before I get into the details of member functions, here is the list of language features:   

  • Script support for tags
  • Member functions for CF data type/data structure
  • Improved JSON serialization
  • Easy to use CF functions for Query tag
  • Elvis operator (?:)
  • Promoting built-in CF function to first class 
  • Miscellaneous new functions: QueryGetRow, ListEach and others. 
ColdFusion predates object-oriented programming (OOPs) and hence did not have support for OOPs syntax. If you had to perform an action on an array, a struct or say on any other CF datatype, you had to call the headless functions like “ArrayAppend” or “StructFind” prior to Splendor. Now, with addition of “Member functions” support in Splendor, you can now enjoy writing your code in true object oriented-style and can call find() method on a struct object. For instance, empStruct.find(“empID”). The code snippet shown below will help you visualize these two different coding styles:


Headless function

<cfscript>
     ArrayAppend(empArray, newObject);
     StructIsEmpty(empStruct);
</cfscript>

As member function of array/Struct

<cfscript> 
     empArray.append(newObject);
     empStruct.isEmpty();
</cfscript>

The Member function support in Splendor is quite exhaustive and covers most of the data types present in ColdFusion. The complete list of data types supported are:

  1. String
  2. List
  3. Array
  4. Struct
  5. Date
  6. Image
  7. Query
  8. SpreadSheet
  9. XML
Member function supported under each data type has been listed in ColdFusion Splender public beta documentation. Please see the documentation for more details.
Stay tuned for more on language enhancements in Splendor..  

Language Enhancements in ColdFusion Splendor

Download the public beta of ColdFusion Splendor from here

Various
enhancements have been added to the core CFML language to provide a better
development experience. Script support for CF
tags and member functions for CF data structure were long pending feature requests and we are
happy to add these two along with a few more enhancements in ColdFusion Splendor (codename). The following list shows the enhancements made in the CFML language:

  • Script support for tags
  • Member functions for CF data type/data structure
  • Improved JSON serialization
  • Easy to use CF functions for Query tag
  • Elvis operator (?:)
  • Promoting built-in CF function to first class 
  • Miscellaneous new functions: QueryGetRow, ListEach and others. 
We will be doing a series of blog posts on language enhancements and this post will only be on the Script support for tags. 

Script
support for tags
Traditionally, while coding in script syntax, you have to switch to tag-based syntax if you have to use CF tags. The reason being, the CF tags, barring
few, were not available in the script syntax.
 ColdFusion Splendor onwards, most of the ColdFusion tags are made available to be used in the CFScript block. Now, you 
can  invoke most of the CF tags within the CFScript blocks. One more good thing about the current implementation is that it will automatically take care of any future tag being added to the CF language. 

Case 1: Simple tag with no child/body.

  <cfscript>
   cfpdf (action=”getInfo”,  name=”pdfVar”,  source=”CF10MigrationGuide.pdf”);
  </cfscript>  

Note: The tag attributes should be enclosed within the parenthesis and must be comma-separated.

Case 2: Tags with child tags/body.

  <cfscript>
    cfform (name='myForm', acton='')
    {
         cfgrid (name="myGrid", query='empQuery')
        {
             cfgridcolumn (name='firstName', id='firstName', type='string');
             cfgridcolumn (name='lastName', id='LastName', type='string');
        }  
    }
  </cfscript>  

Note: The child tag (and the body in general) should be enclosed in curly brackets, as a function block

Case 3: Custom tag

ColdFusion provides three different ways to write custom tags as shown in the following list:

  1. cfmodule based custom tags (supported in Splendor)
  2. cfm file based custom tags (supported in Splendor)
  3. Prefix based custom tags (not supported)
    // Tag based syntax
    <cf_happybirthday name="John" birthDate="December 5, 1987">
    
     //Script based syntax.
     <cfscript>     
         cf_happybirthday(name="John", birthDate="December 5, 1987");
     </cfscript>  

Stay tuned for more on the language enhancements. Please refer to the ColdFusion Splender public beta documentation for more details.