Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 417
  • Last Modified:

Coldfusion cfobject general coding

I guess I just don't understand object oriented coding using cfobject type=java.  Specifically I am using the Exchange EWS managed API.  I'm stuck on updating the appointment item.  I seem to be binding to the item as I can display the start time, the end time, and the subject.  But when I do appointment.update I get one of several errors depending on the params I pass.

appointment.Update();   "The Update method was not found"

appointment.Update(ConflictResolutionMode, SendInvitationsOrCancellationsMode);   "Variable CONFLICTRESOLUTIONMODE is undefined."

appointment.Update('ConflictResolutionMode', 'SendInvitationsOrCancellationsMode');   "The Update method was not found"

<cfobject type="Java" class="microsoft.exchange.webservices.data.ExchangeService" name="service">
		<cfset service.init()>
		<cfobject type="Java" class="microsoft.exchange.webservices.data.ExchangeVersion" name="version">
		<cfset service.init(version.Exchange2010)>
		<cfobject type="Java" class="microsoft.exchange.webservices.data.WebCredentials" name="credentials">
		<cfset Arguments.Pword = Trim(FetchExchangePassword(Arguments.EmailAddress)) />
			<cfset credentials.init("#Arguments.EmailAddress#","#Arguments.Pword#")>
			<cfset service.setCredentials(credentials) />
			<cfobject type="Java" class="java.net.URI" name="uri">
			<cfset uri.init("exchabc.serverdata.net/EWS/Exchange.asmx?wsdl")>
			<cfset service.setUrl(uri) />
			<cfobject type="Java" class="microsoft.exchange.webservices.data.Appointment" name="appointment">
			<cfobject type="Java" class="microsoft.exchange.webservices.data.AppointmentSchema" name="appointmentschema">
			<cfset appointment.init( service )>
			<cfobject type="Java" class="microsoft.exchange.webservices.data.PropertySet" name="propertyset">
			<cfset propertyset.init()>
			<cfobject type="Java" class="microsoft.exchange.webservices.data.ItemId" name="thisitemid">
			<cfset thisitemid.init("#arguments.ExchangeID#")>
			<cfobject type="Java" class="microsoft.exchange.webservices.data.MessageBody" name="MessageBody">
			<cfset appointment = appointment.Bind(service, thisitemid) />
			<cfscript>
					appointment.setStart(#StartDate#);
					appointment.setEnd(#EndDate#);
					appointment.setSubject("#Arguments.EventName#");
					appointment.setBody(MessageBody.getMessageBodyFromText("#Arguments.EventDescription#"));
					appointment.Update('ConflictResolutionMode', 'SendInvitationsOrCancellationsMode');
			</cfscript>

Open in new window


In the appointment class there is the method;
update(microsoft.exchange.webservices.data.ConflictResolutionMode, microsoft.exchange.webservices.data.SendInvitationsOrCancellationsMode)
0
lanterv
Asked:
lanterv
  • 2
  • 2
1 Solution
 
_agx_Commented:
(I don't have access to an Exchange2010 server, so unfortunately can't test your code ...)

A few observations that might help ... Rather than mixing cfml and cfscript, it's better to pick a single style. Preferably cfscript since it's more familiar to the java experts (who are more likely to be familiar with EWS than CF-ers). I attempted to convert your code to CFSCRIPT.  Run the example below.  Assuming there are no typos, you get the same error you're getting now ... and we can go from there.


The thing to keep in mind about using java or .net classes is that they're not native code. So don't expect CF to provide detailed error messages.  It won't.  CF won't tell you if you passed a method a "thing-a-ma-bob" when it was really expecting a "what-ya-callit" object instead. Nor will it tell you if you passed in 2 "thing-a-ma-bob"'s when the method was expecting 3 of them. CF will only return one of a few generic messages like "can't find method...". As you get familiar with using java objects you get to know what those error message mean and now how to fix it.  The good news is that about 95% of the time the cause is one of a few common mistakes:

- The method name is misspelled
- You're called a method with the wrong number or type of arguments
- You forgot to create or initialize the right java object

You have to use the API to understand what the method is expecting. It also helps to just create an instance of the class. Dump it and look for the method you need. Compare it to what the API tells you. Take your appointment class.

     // this is just for testing.  create the class
    appointment = createObject("java", "microsoft.exchange.webservices.data.Appointment");
    // then dump it. look for the update(...) method
    writeDump( appointment );

Open in new window


Dumping it should show a single update(..) method that looks like this.

     
update(  
       microsoft.exchange.webservices.data.ConflictResolutionMode
      , microsoft.exchange.webservices.data.SendInvitationsOrCancellationsMode
     ) 

Open in new window


That's the method "signature". Or in other words, the name of the method and what "type" of parameters it expects, and how many. Just like when you dump a cffunction.  

appointment.Update();   "The Update method was not found"

You can see in the earlier dump that method expects 2 parameters. You passed in 0. That's why you get an error. CF couldn't find a method named "update" with 0 parameters. (If you read over the error message details, it mentions this as a possible cause).

appointment.Update( ConflictResolutionMode,  SendInvitationsOrCancellationsMode );   "Variable CONFLICTRESOLUTIONMODE is undefined."

That's strictly a CF error. You didn't create variables named "ConflictResolutionMode" or "SendInvitationsOrCancellationsMode". Hence the undefined error. The same thing would happen if you to use any variable that didn't exist ie <cfdump var="#ThisVariableNameDoesntExist#">

appointment.Update( 'ConflictResolutionMode',  'SendInvitationsOrCancellationsMode' );  


There you're passing in the correct number of parameters, but ... they're the wrong type.  Look at the method signature again.  The parameter names

             * microsoft.exchange.webservices.data.ConflictResolutionMode
             * microsoft.exchange.webservices.data.SendInvitationsOrCancellationsMode

... tell you the TYPE of object you need to pass in. (Those are EWS java classes). That means you can't just pass in the words "ConflictResolutionMode". You need to actually create instances of those classes. Same as you did for the service and all the other ones ...

Look up the EWS class ConflictResolutionMode API. Figure out how to create an instance of it. Lather, rinse, repeat for the SendInvitationsOrCancellationsMode class. Once you've created the two objects - only then can you call the update(...) method.

Make sense?

CFSCRIPT

<cfscript>
	// declare all your arguments in one place
	Arguments.ExchangeID = "something...";
	Arguments.EmailAddress = "something...";
	Arguments.EventName = "something...";
	Arguments.EventDescription = "something...";
	Arguments.Pword = Trim(FetchExchangePassword(Arguments.EmailAddress));
	StartDate = "something...";
	EndDate = "something...";
	

	uri = createObject("java", "java.net.URI").init("exchabc.serverdata.net/EWS/Exchange.asmx?wsdl");
	version = createObject("java", "microsoft.exchange.webservices.data.ExchangeVersion");
	credentials = createObject("java", "microsoft.exchange.webservices.data.WebCredentials").init( Arguments.EmailAddress , Arguments.Pword );

	// initialize service
	service = createObject("java", "microsoft.exchange.webservices.data.ExchangeService").init(version.Exchange2010);
	//service.setCredentials( credentials );
	service.setUrl( uri );


    // create appointment properties
	appointment = createObject("java", "microsoft.exchange.webservices.data.Appointment").init( service );
	writeDump(appointment);
	appointmentschema = createObject("java", "microsoft.exchange.webservices.data.AppointmentSchema");
	propertyset = createObject("java", "microsoft.exchange.webservices.data.PropertySet").init();

    // initialize all in one line
	thisitemid = createObject("java", "microsoft.exchange.webservices.data.ItemId").init( arguments.ExchangeID);
	MessageBody = createObject("java", "microsoft.exchange.webservices.data.MessageBody");
	appointment = appointment.Bind(service, thisitemid);
	appointment.setStart( StartDate );
	appointment.setEnd( EndDate );
	appointment.setSubject( Arguments.EventName );
	appointment.setBody( MessageBody.getMessageBodyFromText( Arguments.EventDescription ));
	appointment.Update('ConflictResolutionMode', 'SendInvitationsOrCancellationsMode');
</cfscript>

Open in new window

0
 
lantervAuthor Commented:
That explains a lot.  It helped me decipher the Microsoft documentation.  They could have done a much better job or posted a certification level required to read the documentation. :)  Many thanks.
0
 
lantervAuthor Commented:
Thank you.
0
 
_agx_Commented:
Yeah, there's a bit of learning curve. You need to know more than just cfml before you can use java/.net objects from CF. You have to know something about the API you're using as well.

> They could have done a much better job

Well on the one hand, it makes sense that they don't write detailed documentation or error handling for every 3rd party app or API you can use from within CF, because it's not their product.  Documentation is the job of whoever wrote the lib (MS, Apache, etc...). That said, I agree they could do a better job of documenting what you should and shouldn't expect to see when working with java/.net object in general. How to interpret the cfdump of an object, common error messages, etc... I stumbled through it and learned most of it through lots of cfdumps and trial and error ;-)  On the plus side, it's a one time event. Once you figure out the rules for one lib it's the same for all of them.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now