Reputation: 4582
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
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
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
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