access attributes of an object using COM interface - java

am using JACOB as a bridge with java to access objects of a simulator (PTV vissim)to be able to manipulate it in real time , most objects has methods and properties... i was going well , because i was using the ...
getProperty and invoke functions but now I need to access an object attribute e.g. name but i don't know which function should I use , the object am dealing with is an instance of
ActiveXComponent
package com.vissim;
import java.util.List;
import java.util.Scanner;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Variant;
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
Vissim vissim = new Vissim();
vissim.start();
vissim.LoadNet("H:\\MY VISSIM\\projects\\new.inpx");
Net net = new Net(vissim);
ActiveXComponent linkContainer = net.getNetProperty("links");
System.out.println("links fetched");
ActiveXComponent link =linkContainer.invokeGetComponent("itemByKey", new Variant(1));
// the problem is here , i need to do something like
//link.getProperty("Attributes");
System.out.println("we are here ");
}

Use com4j to generate some wrapper files. com4j will probably crash saying that it is unable to handle some of the types, but if you go to the generated java files you will see the names of all of the methods that can be called from the Dispatch object e.g. ISimulation.java will have all of the methods that you can call on a Simulation object.
Here is an example of some function / method calls:
Dispatch vissim = VISSIM.getObject();
Dispatch.call(vissim, "loadNet", new Object[]{new Variant("C:\\Users\\userName\\workspace\\VISSIMNetworks\\network.inp"), new Variant(0)});
Dispatch simulation = Dispatch.call(vissim, "simulation").toDispatch();
Dispatch.call(simulation, "runContinuous");

Related

How to load Java Swing MainJFrame with classes instance and data from ANOTHER Java Class?

Hello Guys I have my swing application running but I need to create an "initialization class" where I create instances with data to populate the program when I run it
If I create an instance with data in the MainJFrame constructor it's working perfectly but I need to populate the MainJFrame that will send it through all the panels from ANOTHER CLASS
Here is my MainJFrame Code:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package UserInterface;
import Business.Initialization;
import Business.Inventory;
import Business.InventoryList;
import Business.Product;
import Business.ProductCatalog;
import Business.Store;
import Business.StoreDirectory;
import UserInterface.StarMarketAdmin.MarketAdminWorkArea;
import UserInterface.StoreAdmin.LoginStoreAdmin;
import java.awt.CardLayout;
import java.util.Collections;
import javax.swing.SwingUtilities;
public class MainJFrame extends javax.swing.JFrame {
/**
* Creates new form MainJFrame
*/
private StoreDirectory storeDirectory;
private InventoryList inventoryList;
private ProductCatalog productCatalog;
private Store store;
public MainJFrame() {
initComponents();
this.storeDirectory = new StoreDirectory();
this.inventoryList = new InventoryList();
this.productCatalog = new ProductCatalog();
this.store = new Store();
}
private void btnMarketAdminActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
MarketAdminWorkArea panel = new MarketAdminWorkArea(userProcessContainer,storeDirectory,inventoryList,productCatalog,store);
userProcessContainer.add("MarketAdminWorkArea", panel);
CardLayout layout = (CardLayout) userProcessContainer.getLayout();
layout.next(userProcessContainer);
}
private void btnStoreAdminActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
LoginStoreAdmin panel = new LoginStoreAdmin(userProcessContainer,storeDirectory,inventoryList,productCatalog);
userProcessContainer.add("LoginStoreAdmin", panel);
CardLayout layout = (CardLayout) userProcessContainer.getLayout();
layout.next(userProcessContainer);
}
}
Now if I create an instance like:
Store s = storeDirectory.addStore();
s.setStoreName("Eddie's Market");
s.setStreet("Plainfield Pike");
s.setCity("Johnston");
s.setState("RI");
s.setCountry("USA");
in the MainJFrame it's working 100% but I need to create it in another class and call it in the MainJFrame to send it from there to all the other pannels.
How can I do this ?
create public functions to acces the private class from outside
not sure what you want exactly, but the options are endless
like
public void initStore(){
}
or just get it
public Store getStore(){
retturn store;
}
or even create and return it from there:
public Store storeFactory(){
// code here
return store;
}
or if you want another store and return it
public Store storeFactory(){
// code here to create a new store
return store2;
}
* NOT ADVISED but also an option: static *
you can also create a static one, even make it public, however public access is not the nicest way. Better keep it private and work with function as above to get it. In normally would not advice static usage like this... but assuming the MainFrame is the main program... in this case there might be an exception on the not to use static ....
private static Store store;
or
public static Store store;
than you can access it from everywhere by:
MainJFrame.store
* end static remark *
but maybe you just meant this:
public putStore(Store store){
this.store=store;
}
so you can create it in other class, and get it from other classes
in the other class to create it you migth even first get it (init it in the mainFrame with null:
private Store store=null;
in the other class:
Store store = mainframe.getStore();
// code to create it
or only create it if not yet created:
if (store==null){
// Only create if still null
// code to create it here
}
// and here use it, just created or not
Migth be a weird and 'know it all' like advice, but:
all of the above is basic java knowledge about public, private, static and so on.... might look in to some tutorials, to understand the basic things.
Java can be a pain in the... in case you do not understand it (memory leaks and so on...) so please be sure you know what you do.... (in case you want to use it professionaly)
In java there is a big difference in declaring it, and initialising it:
this is a declaration:
private Store store:
this is the init:
store = // something, even putting it to null is an init
and the combination of declare and init:
private Store store=null;
the last one you need before you can call it from other classes, because you actually will not get the object, but a pointer tot the object.
To have a pointer, you need tot init it, than init to null is enough.... so there is at least a pointer.
Understanding the way of pointers and how things are passed in java, will save some memory issues in bigger programs.
Inject this Store instance into the MainJFrame constructor.
The Store class will hold the data and you can access it through get methods.
Have you thought about that?

Call DLL from Java using JNA

I am new to accessing DLLs from Java using JNA. I need to access methods from a class within a DLL(written in .net). Form this sample DLL below, I am trying to get AuditID and Server ID. I am ending with the following error while I am running my code. Any guidance really appreciated.
/// Error ///
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'GetEnrollcontext': The specified procedure could not be found.
//DLL File Code//
SampleDLL.ProfileEnroll enrollcontext = new SampleDLL.ProfileEnroll();
enrollcontext.Url =” url”;
enrollcontext.AuditIdType = SampleDLL.ProfileId;
enrollcontext.AuditId = “22222222 “;
enrollcontext.ServerId = “server1”;
/// Java Code ///
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import dllExtract.DLLExtractTest.SampleDLL.Enrollcontext;
public class SampleDLLExtract {
public interface SampleDLL extends Library {
SampleDLL INSTANCE = (SampleDLL) Native.loadLibrary("SampleDLL",
SampleDLL.class);
public static class Enrollcontext extends Structure {
public String auditId;
public String serverId;
}
void GetEnrollcontext(Enrollcontext ec); // void ();
}
public static void main(String[] args) {
SampleDLL sdll = SampleDLL.INSTANCE;
SampleDLL.Enrollcontext enrollContext = new SampleDLL.Enrollcontext();
sdll.GetEnrollcontext(enrollContext);
System.out.println(sdll.toString(sdll.GetEnrollcontext(enrollContext)));
}
}
in fact there is a solution for you to use C#, VB.NET or F# code via JNA in Java (and nothing else)! and it is also very easy to use:
https://www.nuget.org/packages/UnmanagedExports
with this package all you need to do is, add [RGiesecke.DllExport.DllExport] to your methods like that:
C# .dll Project:
[RGiesecke.DllExport.DllExport]
public static String yourFunction(String yourParameter)
{
return "CSharp String";
}
Java Project:
public interface jna extends Library {
jna INSTANCE = (jna) Native.loadLibrary("yourCSharpProject.dll", jna.class);
public String yourFunction(String yourParameter);
}
use it in the code:
System.out.println(jna.INSTANCE.yourFunction("nothingImportant"));
Viola!
As already mentioned it works very easy, but this solution has some limitations:
only available for simple datatypes as parameter & return values
no MethodOverloading available. yourFunction(String yourParameter) and yourFunction(String yourParameter, String yourSecondParameter) does not work! you have to name them differently
Use arrays as parameter or return values. (JNA offers StringArray, but I am not able to use them in C#) (maybe there is a solution, but I couldn't come up with one so far!)
if you export a method you can't call it internally in your C# code (simple to bypass that by the following:
.
[RGiesecke.DllExport.DllExport]
public static Boolean externalAvailable(String yourParameter)
{
return yourInternalFunction(yourParameter);
}
With C# it works great, with VB.NET and F# I have no experience.
hope this helps!

Overriding a method in a subclass

I'm trying some alterations in minecraft src. I'm trying to override a method in a class so I don't have to edit the original class.
In the regular class I want to alter this method:
public void sendChatMessage(String par1Str)
{
this.sendQueue.addToSendQueue(new Packet3Chat(par1Str));
}
So in my subclass I have this code:
package cobalt.gui;
import cobalt.hacks.*;
import net.minecraft.client.Minecraft;
import net.minecraft.src.EntityClientPlayerMP;
import net.minecraft.src.NetClientHandler;
import net.minecraft.src.Session;
import net.minecraft.src.World;
public class Console extends EntityClientPlayerMP {
public Console(Minecraft par1Minecraft, World par2World,
Session par3Session, NetClientHandler par4NetClientHandler) {
super(par1Minecraft, par2World, par3Session, par4NetClientHandler);
}
#Override
public void sendChatMessage(String par1Str) {
if (par1Str.startsWith(".help")) {
//Do stuff
return;
}
}
}
From my understanding, anytime a method is called, it should be "redirected" for the subclass to handle? (Tell me if I'm wrong ha)
The if statement does work correctly if I modify the original class.
Thank you very much!
This would only work if somehow the rest of the minecraft code starts using your class, Console, where it meant to use EntityClientPlayerMP. Without that, your function will not be called.
If you want to change the behavior of the game, the easiest way would be to change EntityClientPlayerMP itself. If you want to use the modified class Console elsewhere in the code, then what you have done is fine.
It depends on the actual object type. If the object is of type Console e.g. EntityClientPlayerMP obj = new Console(..) and obj.sendChatMessage(..) it'll work. But if the object itself is of type EntityClientPlayerMP like new EntityClientPlayerMP(..) It won't work

Compile and create instance of a new java program from existing java program

I am writing a java program in eclipse to extract forms from lotusnotes db. Whenever I get a form I need to create a .java file containng a class with same name as of form. Then I have to compile this new .java class which gives me .class file & hence I can create an instance of that new class. I need to know whether this approach of creating,compiling & instantiating a new class is possible from a single existing java program.
My pseudocode goes below
import java.util.Iterator;
import de.bea.domingo.*;
import java.util.List;
import java.io.*;
public class LotusNotesDBExtraction
{
public static void main(String[] args) throws DNotesException,IOException
{
DNotesFactory factory = DNotesFactory.getInstance();
DSession session = factory.getSession();
DDatabase database = session.getDatabase("", "employee.nsf");
List formlist=database.getForms();
//System.out.println("Number of forms are :"+formlist.size());
for(int i=0;i<formlist.size();i++)
{
DForm formn=(DForm)(formlist.get(i));
DForm formname= database.getForm(formn.getName());
**//Creating a class in a file
FileWriter outputfile = new FileWriter("D:\\Lotusnotesformfiles\\"+formn.getName()+".java",true);
BufferedWriter out = new BufferedWriter(outputfile);
out.write("public class "+formn.getName()+" {");
out.newLine();
out.flush();**
try
{
**//Compile the class here**
Process p1 = Runtime.getRuntime().exec("cmd javac \"D:\\Lotusnotesformfiles\\"+formn.getName()+".java\"");
System.out.println("compiled");
}
catch(IOException x)
{
x.printStackTrace();
}
**//instantiate the new class here**
}
}
But I am not able to get .class file for the new class. Can I instantiate the new class in the same program?? I was stuck at this point. Can any please help me
You should be able to do much, if not all, of this using the Reflection API, which allows you to modify classes at runtime, inspect their contents, and even dynamically load classes (for example, after compilation).

renaming DLL functions in JNA using StdCallFunctionMapper

I'm trying to use JNA with a DLL in Windows, so far I was able to successfully call a function called c_aa_find_devices(). But all the functions start with c_aa and I would like to rename it to find_devices().
From what I gather the way to do this is with StdCallFunctionMapper but I can't find the documentation of how to use it in an example (i.e. how to map a DLL function by name or by ordinal to a desired name in the wrapped Java library interface). Any suggestions on where the docs are?
A complete working example, using a function mapper.
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.win32.StdCallFunctionMapper;
import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class JnaTest {
static {
Map options = new HashMap();
options.
put(
Library.OPTION_FUNCTION_MAPPER,
new StdCallFunctionMapper() {
HashMap<String, String> map = new HashMap() {
{
put("testMethod", "testMethod#0");
}
};
#Override
public String getFunctionName(NativeLibrary library, Method method) {
String methodName = method.getName();
return map.get(methodName);
}
}
);
File LIB_FILE = new File("test.dll");
Native.register(NativeLibrary.getInstance(LIB_FILE.getAbsolutePath(), options));
}
private static native int testMethod();
public static void main(String[] args) {
testMethod(); // call the native method in the loaded dll with the function name testMethod#0
}
}
Using StdCallMapper won't do good - it is supposed to map werid windows std lib names that have embedded total byte lenght of parameters embedded as part of the name. Since it is done to std lib only (just guessing on that, but 99% you'r functions are not the case).
If your dll uses some common prefix on all functions you need just to use something like:
class Mapper implements FunctionMapper{
public String getFunctionName(NativeLibrary library, Method method) {
return GenieConnector.FUNCTION_PREFIX + method.getName();
}
}
Where GenieConnector.FUNCTION_PREFIX is that common prefix. Bear in mind that i implement FunctionMapper, not extend StdCallMapper
From the documentation you need to provide a FunctionMapper in the original call to loadLibrary that converts the name. However you also need to keep the standard call mapping so try something like the following:
Map options = new HashMap();
options.
put(
Library.OPTION_FUNCTION_MAPPER,
new StdCallFunctionWrapper() {
public String getFunctionName(NativeLibrary library, Method method) {
if (method.getName().equals("findDevices")
method.setName("c_aa_find_devices");
// do any others
return super.getFunctionName(library, method);
}
}
);
Native.loadLibrary(..., ..., options);
All JNA documentation is located at the primary web page, the JavaDoc overview, and the JavaDocs themselves.
The example above is the right idea, in that you need to tweak the function name returned by the generic StdCallFunctionMapper (assuming you're using the stdcall calling convention). However, Method.setName() doesn't exist and you wouldn't want to call it if it did. You'll need to get the String result and replace the Java function name within it with the target native name, e.g.
name = super.getFunctionName();
name = name.replace("find_devices", "c_aa_find_devices");
More generically, you can simply tack on a "c_aa_" prefix to the returned name (or after any leading underscore), since stdcall decorations are at the end of the name.

Categories