It is rather easy to add ECMA style scripting to cold fusion. It simply
requires adding bsf.jar to your classpath and calling it correctly. There
are a few benefits to allowing such scripting. Here are a few:
* Constructers that require / accept nulls can be used in ECMA blocks and
then the results can be passed to CF
* When creating lots of objects it seems to be faster then a lot of
createObject() calls
* Standard scripting style (for example, you can use > instead of gt and
x++ instead of x=x+1 - which would help developers who are used to
JavaScript, C, C++, Java, C#, etc)
Some Examples:
With ECMA Scripting in CF you can do standard xml function and document
building which adds a whole new layer of xml integration. For example:
<...>
builder = docfactory.newDocumentBuilder();
doc = builder.parse(new java.io.File("neo-mail.xml"));
doc.appendChild(doc.createElement("fresh"));
variables.put("mydoc",doc);
</...>
You can also script tasks in a "normal" java way which can add lower level
power to a web application (in line):
<...>
fin = new java.io.FileInputStream(new java.io.File("neo-cron.xml"));
crazy = new java.lang.StringBuffer();
while((i=fin.read()) != -1){
crazy.append(String.fromCharCode(i));
}
</...>
I think that is not only cool, but allows for powerful tweaking!
Things That Suck:
The real reason I wanted in line java was to be able to make objects and
use them in my apps (admin extends client - etc, etc). I was hoping ECMA
would let that happen, it kind of does but not really. For example:
<...>
obj = new Object();
function _attach(){
return 1;
}
obj.prototype.attach = _attach;
variables.put("myobj",obj);
</...>
returns a "NativeJavascriptObject" which I cannot use in CF. Which really
sucks. I can pass it around - but it seems useless in CF.
Summary:
It would be very easy to add a ECMA style scripting into CFMX (I did it -
Macromedia can). I think that it would add more power to CF and help out in
getting people to switch to CF.
In playing with this I have learned quite a bit about MX an am happy to
report that is is done really well - like cf arrays seem to be
java.util.Vectors; I think that is an excellent choice.
I am done playing with this as I have more pressing obligations (like my
job :). If anyone wants to play with this let me know and I'll give you the
low down.
+===========================================================================
+
How to do it:
first get bsf.jar and add it to your classpath and restart cfmx (look on
google)
then make a page like (watch out for line wrap):
(I called it cfjava.cfm)
<cfparam name="attributes.script" default="" type="string"/>
<cfparam name="attributes.language" default="javascript" type="string"/>
<cfscript>
//create a bean manager
if(not isDefined("cfjava.manager"))
cfjava.manager = createObject("java","com.ibm.bsf.BSFManager");
//get a handle to the cf-factory
if(not isDefined("cfjava.factory"))
cfjava.factory =
createObject("java","coldfusion.server.ServiceFactory");
//make sure session, and variables have something in them or
//they wont be able to be passed
caller.variables.cj=true;
caller.session.cj=true;
//load the scopes as beans
cfjava.manager.declareBean("cgi", caller.cgi, caller.cgi.getClass());
cfjava.manager.declareBean("variables", caller.variables,
caller.variables.getClass());
cfjava.manager.declareBean("session", caller.session,
caller.session.getClass());
cfjava.xmlfactory =
createObject("java","org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
//TODO: load all services//
cfjava.manager.declareBean("docfactory",cfjava.xmlfactory,
cfjava.xmlfactory.getClass());
cfjava.manager.declareBean("runtime", cfjava.factory.RuntimeService,
cfjava.factory.RuntimeService.getClass());
cfjava.manager.declareBean("client", cfjava.factory.ClientScopeService,
cfjava.factory.ClientScopeService.getClass());
//////////////////////////
//Execute an expression.
cfjava.manager.exec(
"#attributes.language#", "javascript_code", 0, 0, attributes.script
);
</cfscript>
+==========================================================+
Then when you want to use it call it like so:
(I called this page scriptcaller.cfm)
<cfsavecontent variable="javascript_code">
crazy=null;
variables.put("vectortest", new java.util.Vector());
variables.put("hashtest", new java.util.HashMap());
try{
fin = new java.io.FileInputStream(
new java.io.File("neo-cron.xml")
);
crazy = new java.lang.StringBuffer();
while((i=fin.read()) != -1){
crazy.append(String.fromCharCode(i));
}
}catch(e){
doc=e.toString();
}
variables.put("jReturn",crazy.toString());
</cfsavecontent>
<cfmodule template="cfjava.cfm" script="#javascript_code#"/>
<cfdump var="#variables#"/>
+========================================================+
Have fun
Rob
http://treebeard.sourceforge.net
http://ruinworld.sourceforge.net
Scientia Est Potentia
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
Archives: http://www.houseoffusion.com/cf_lists/index.cfm?forumid=4
Subscription:
http://www.houseoffusion.com/cf_lists/index.cfm?method=subscribe&forumid=4
FAQ: http://www.thenetprofits.co.uk/coldfusion/faq
Structure your ColdFusion code with Fusebox. Get the official book at
http://www.fusionauthority.com/bkinfo.cfm