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

Reply via email to