Jason -

I replied to someone recently with a similar question, see below:

I was in the same position as you trying to find good examples of a java 
implemented XPCOM object.  I am actually using JavaXPCOM to allow a 
javascript web app (embedded in an eclipse rcp), talk to eclipse java code.

There are several parts to getting the XPCOM objects implemented and 
registered with the system.

To start with, you will need xulrunner 1.8.1.3 installed, gecko-sdk and 
wintools.zip.  Specifically in wintools.zip is a tool call xpidl.exe. 
This tool will be used to compile your Language independent IDL file 
into a XPT file.  The XPT file is a typelib for the XPCOM system 
(basically an interface that the xpcom system understands).  You will 
drop this into the components directory of xulrunner and then you will 
be able to get a reference to it from other languages - in your case 
from javascript/XUL.  There are plenty of IDL files in the gecko-sdk and 
you should take a look at them for more examples.  For the example i'm 
going to show you, there is only one method -> openBranch(String 
branchID).  This is the method we want to expose to any clients that 
have a hold of our xpcom object.

First the IDL file.  This is a language independent version of the 
interface.

My IDL files looks like this:
   #include "nsISupports.idl"

   [scriptable, uuid(6fde3824-7665-11dc-8314-0800200c9a66)]

   interface IAECom : nsISupports {
       void openBranch(in string branchID);
   };

Notice the uuid.  This is a UNIQUE id for the *interface*.  I've been 
using a website that generates them for you but you can also download a 
tool called guidgen.exe.

Now take the idl files and use xpidl.exe with the "-m typelib" switch 
and it will spit out the XPT files.  Again, this is the file you will 
put in the components directory.

Next i would then use the xpidl.exe tool with the "-m java" switch to 
generate a java interface.  We will implement this interface - which is 
the actual implementation of the XPCOM object.
Now notice that you will need to add MozillaInterfaces.jar found within 
the XULRunner 1.8.1.3 or within the gecko-sdk.

A few things to not about this implementation.
-The CID and the Contract_ID are both unique for an Implementation of 
the IAECom component.  The Contract_ID is what can be used later to get 
a reference to the object view javascript.  Say for instance though you 
would like to implement IAECom in a different way, you would use a 
different CID and Contract_ID.
-Notice that my implementation implements the nsIFactory AND the 
nsISupports.  The nsISupports is the main xpcom class that all must 
implement.  The nsIFactory is important because it is used to create an 
instance of the object.

import org.mozilla.interfaces.nsIFactory;
import org.mozilla.interfaces.nsISupports;
import org.mozilla.xpcom.IXPCOMError ;
import org.mozilla.xpcom.XPCOMException;

public class AECom implements IAECom, nsIFactory {

     private String IID = IAECom.IAECOM_IID;
     public static String CID = "{4d1db5b8-7666-11dc-8314-0800200c9a66}";
     public static String CONTRACT_ID = "@com.lombardi/AECom;1";
     private static AECom instance = new AECom();

     public static AECom getInstance() {
         return instance;
     }

     private AECom() {
     }

     public void openBranch(final String branchID) {
        System.out.println("This method was called from the xpcom 
system...BranchID: " + branchID);
     }

     /*  nsISupports Implementation */
     public nsISupports queryInterface(String uuid) {
         if(!uuid.equals(NS_ISUPPORTS_IID) &&
                 (!uuid.equals(NS_IFACTORY_IID)) &&
                 (!uuid.equals(IAECOM_IID))) {
             throw new XPCOMException(IXPCOMError.NS_ERROR_NOT_IMPLEMENTED);
         }
         return this;
     }

     /* nsIFactory Implementation */
     public nsISupports createInstance(nsISupports aOuter, String iid) {
         if (aOuter != null) {
             throw new XPCOMException(IXPCOMError.NS_ERROR_NO_AGGREGATION );
         }
         if (!iid.equals(IID) && 
!iid.equals(nsISupports.NS_ISUPPORTS_IID)) {
             throw new XPCOMException(IXPCOMError.NS_ERROR_INVALID_ARG);
         }
         return instance;
     }


     public void lockFactory(boolean lock) {
         /* Don't know what to do here... Doesn't seem to matter though*/
     }
}

Since it's implemented in Java, you will want to register is on your 
java startup.  To do this you need to get a hold of the Mozilla class. 
Through it you should be able to get the registration manager and and 
register your component.  There are plenty of examples of getting the a 
Mozilla object on the XULRunner 1.8.1.3 project page.

public void registerComponent() {
         Mozilla mozilla = Mozilla.getInstance ();
         AECom aecom = AECom.getInstance();
         String branchID = "7894702589743058";

         nsIComponentRegistrar registrar = mozilla.getComponentRegistrar();

         registrar.registerFactory(AECom.CID, "AECom", 
AECom.CONTRACT_ID, aecom);

         // Simple test to see if it was registered
         // nsIComponentManager comMgr = mozilla.getComponentManager();
         // IAECom aecom2 = 
(IAECom)comMgr.createInstance(AECom.CID,null,AECom.IAECOM_IID);
         // aecom2.openBranch(branchID);
}

I did a lot of educated guessing here (based on some javascript 
examples) since i couldn't really find an examples but it seems to work 
without any problems.


After this is complete, you should be able to do something like this in 
javascript:
         try{
 
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
             var oMyComponent = 
Components.classes['@com.lombardi/AECom;1'].createInstance(Components.interfaces.IAECom);
             if (oMyComponent == null) {
                 alert("oMyComponent is null");
             }

             oMyComponent.openBranch (branchID);
         } catch(e) {
             alert(e);
         }


wintools.zip -> 
http://ftp.mozilla.org/pub/mozilla.org/mozilla/source/wintools.zip
gecko-sdk -> http://developer.mozilla.org/en/docs/Gecko_SDK
GuidGen -> http://www.famkruithof.net/uuid/uuidgen
xulrunner -> http://developer.mozilla.org/en/docs/XULRunner
xulrunner 1.8.1.3 download -> 
http://stage.mozilla.org/pub/mozilla.org/xulrunner/releases/1.8.1.3/contrib/win32/

Example snippet from eclipse -> 
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet267.java?view=co
XULPlanet xpcom reference -> http://www.xulplanet.com/references/xpcomref/

Hope that helps,
Bryan Campbell
Software Engineer
Lombardi Software

bc wrote:
> Jason -
> 
> So to be clear you want to be able to call JavaScript functions, and 
> interact with the DOM from a java application?
> 
> -Bryan
> 
> Jason Ward wrote:
>> I would like to embed the necessary components into a server side java
>> application that would allow the application to load a web page from a 
>> url
>> (including dependencies like .js files), construct the dom, and execute
>> JavaScript within the page.  I do not need to render the page 
>> graphically.
>> I do need to be able to interact with the JavaScript and DOM from Java.
>>  
>> Which components would I need to use to achieve this?  If anyone has any
>> pointers or examples that would be greatly appreciated too.
>>  
>> Thank you!
_______________________________________________
dev-embedding mailing list
dev-embedding@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-embedding

Reply via email to