E-Madd
E-Madd

Reputation: 4582

Java cfObject with method names that are CF reserved words

I've been working on a Braintree integration in ColdFusion. Braintree does not directly support CF, but they provide a Java library and everything I've done so far has worked really well... until now. It appears that some of the objects (particularly the search functionality) have methods that are not accessible from CF and I suspect it's because they are CF reserved words, such as "is" and "contains". Is there any way to get around this?

<cfscript>
gate = createObject( "java", "com.braintreegateway.BraintreeGateway" ).init(env,merchant.getMerchantAccountId(), merchant.getMerchantAccountPublicSecret(),merchant.getMerchantAccountPrivateSecret());
req = createObject( "java","com.braintreegateway.CustomerSearchRequest").id().is("#user.getUserId()#");
customer = gate.customer().search(req);
</cfscript>

The error thrown: Invalid CFML construct ... ColdFusion was looking at the following text: is

Upvotes: 2

Views: 821

Answers (3)

Kevin Mansel
Kevin Mansel

Reputation: 2381

Here is a solution to this problem. At least a fix to get you up and running.

Try this code.

<cfscript>
    //Get our credentials here, this is a custom private function I have, so your mileage may vary
    credentials = getCredentials();

    //Supply the credentials for the gateway    
    gateway = createObject("java", "com.braintreegateway.BraintreeGateway" ).init(credentials.type, credentials.merchantId, credentials.publicKey, credentials.privateKey);

    //Setup the customer search object  
    customerSearch = createObject("java", "com.braintreegateway.CustomerSearchRequest").id();

    //can't chain the methods here for the contains, since it's a reserved word in cf.  lame.
    customerSearchRequest = customerSearch.contains(arguments.customerId);

    //Build the result here
    result = gateway.customer().search(customerSearchRequest);
</cfscript>

Upvotes: 0

Adam Cameron
Adam Cameron

Reputation: 29870

This represents a bug in the CF compiler. There is no rule in CF that one cannot define a method called either is() or this(), and indeed in basic situations there's no problem with calling them either. This code demonstrates:

<!--- Junk.cfc --->
<cfcomponent>
    <cffunction name="is">
        <cfreturn true>
    </cffunction>
    <cffunction name="contains">
        <cfreturn true>
    </cffunction>
</cfcomponent>

<!--- test.cfm --->
<cfset o = new Junk()>

<cfoutput>
    #o.is()#<br />
    #o.contains()#<br />
</cfoutput>

This - predictably - outputs:

true
true

However we have problems if we introduce a init() method to Junk.cfc, thus:

<cffunction name="init">
    <cfreturn this>
</cffunction>

And then adjust test.cfm accordingly:

#o.init().is()#<br />
#o.init().contains()#<br />

This causes a compiler error:

Invalid CFML construct found on line 4 at column 19.

ColdFusion was looking at the following text:

is

[...]

coldfusion.compiler.ParseException: Invalid CFML construct found on line 4 at column 19.

at coldfusion.compiler.cfml40.generateParseException(cfml40.java:12135)

[etc]

There is no valid reason why o.init().is() should not be OK if o.is() is fine.

I recommend you file a bug. I'll vote for it.

As a workaround you should be fine if you use intermediary values, rather than method chaining.

Upvotes: 6

barnyr
barnyr

Reputation: 5678

You can probably use the Java Reflection API to invoke the is() method on your object.

I'd also raise a call with Adobe to see if they'll fix it or provide their own workaround. I can understand disallowing defining your own method or variable called 'is', but attempting to invoke it here should be safe.

Upvotes: 1

Related Questions