Search in sources :

Example 1 with ObjectFactory

use of com.sun.jna.platform.win32.COM.util.ObjectFactory in project jna by java-native-access.

the class SAFEARRAYTest method testADODB.

/**
     * Test assumption: The windows search provider is present and holds at least
     * five entries. If this assumption is not met, this test fails.
     */
@Test
public void testADODB() {
    ObjectFactory fact = new ObjectFactory();
    // Open a record set with a sample search (basicly get the first five
    // entries from the search index
    Connection conn = fact.createObject(Connection.class);
    conn.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';", "", "", -1);
    Recordset recordset = fact.createObject(Recordset.class);
    recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl, System.DateCreated FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1);
    // Save complete list for comparison with subscript list
    List<String> urls = new ArrayList<String>(5);
    List<String> names = new ArrayList<String>(5);
    while (!recordset.getEOF()) {
        WinNT.HRESULT hr;
        // Fetch (all) five rows and extract SAFEARRAY
        SAFEARRAY sa = recordset.GetRows(5);
        assertThat(sa.getDimensionCount(), is(2));
        // Test getting bounds via automation functions SafeArrayGetLBound
        // and SafeArrayGetUBound
        // 5 rows (dimension 1) and 4 (dimension 2) columns should be
        // returned, the indices are zero-based, the lower bounds are
        // always zero
        //
        // Dimensions are inverted between SafeArray and java, so 
        // in this case row dimension 2 retrieves row count,
        // dimension 1 retrieves column count
        WinDef.LONGByReference res = new WinDef.LONGByReference();
        hr = OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(2), res);
        assert COMUtils.SUCCEEDED(hr);
        assertThat(res.getValue().intValue(), is(0));
        hr = OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(2), res);
        assert COMUtils.SUCCEEDED(hr);
        assertThat(res.getValue().intValue(), is(4));
        hr = OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(1), res);
        assert COMUtils.SUCCEEDED(hr);
        assertThat(res.getValue().intValue(), is(0));
        hr = OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(1), res);
        assert COMUtils.SUCCEEDED(hr);
        assertThat(res.getValue().intValue(), is(3));
        // Get dimensions directly from structure
        // lLbound contains lowerBound (first index)
        // cElements contains count of elements
        int row_lower = sa.rgsabound[0].lLbound.intValue();
        int row_count = sa.rgsabound[0].cElements.intValue();
        int column_lower = sa.rgsabound[1].lLbound.intValue();
        int column_count = sa.rgsabound[1].cElements.intValue();
        assertThat(row_lower, is(0));
        assertThat(row_count, is(5));
        assertThat(column_lower, is(0));
        assertThat(column_count, is(4));
        // Use Wrapper methods
        assertThat(sa.getLBound(0), is(0));
        assertThat(sa.getUBound(0), is(4));
        assertThat(sa.getLBound(1), is(0));
        assertThat(sa.getUBound(1), is(3));
        // Columns 1 - 3 return Strings, Column 4 returns a date
        for (int rowIdx = row_lower; rowIdx < row_lower + row_count; rowIdx++) {
            for (int colIdx = column_lower; colIdx < column_lower + column_count; colIdx++) {
                VARIANT result = (VARIANT) sa.getElement(rowIdx, colIdx);
                Pointer pv = sa.ptrOfIndex(rowIdx, colIdx);
                VARIANT result2 = new VARIANT(pv);
                COMUtils.checkRC(hr);
                if (colIdx == 3) {
                    assert (result.getVarType().intValue() & Variant.VT_DATE) > 0;
                    assert (result2.getVarType().intValue() & Variant.VT_DATE) > 0;
                } else {
                    assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0;
                    assert (result2.getVarType().intValue() & Variant.VT_BSTR) > 0;
                }
                // Only clear result, as SafeArrayGetElement creates a copy
                // result2 is a view into the SafeArray
                OleAuto.INSTANCE.VariantClear(result);
            }
        }
        // Access SafeArray directly
        sa.lock();
        try {
            // Map the returned array to java
            VARIANT[] variantArray = (VARIANT[]) (new VARIANT(sa.pvData.getPointer()).toArray(row_count * column_count));
            for (int rowIdx = 0; rowIdx < row_count; rowIdx++) {
                for (int colIdx = 0; colIdx < column_count; colIdx++) {
                    int index = rowIdx * column_count + colIdx;
                    VARIANT result = variantArray[index];
                    if (colIdx == 3) {
                        assert (result.getVarType().intValue() & Variant.VT_DATE) > 0;
                    } else {
                        assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0;
                    }
                    // see comment for urls
                    if (colIdx == 2) {
                        urls.add(result.stringValue());
                    } else if (colIdx == 1) {
                        names.add(result.stringValue());
                    }
                }
            }
        } finally {
            sa.unlock();
        }
        // Access SafeArray directly - Variant 2
        Pointer data = sa.accessData();
        try {
            // Map the returned array to java
            VARIANT[] variantArray = (VARIANT[]) (new VARIANT(data).toArray(row_count * column_count));
            for (int rowIdx = 0; rowIdx < row_count; rowIdx++) {
                for (int colIdx = 0; colIdx < column_count; colIdx++) {
                    int index = rowIdx * column_count + colIdx;
                    VARIANT result = variantArray[index];
                    if (colIdx == 3) {
                        assert (result.getVarType().intValue() & Variant.VT_DATE) > 0;
                    } else {
                        assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0;
                    }
                    // see comment for urls
                    if (colIdx == 2) {
                        urls.add(result.stringValue());
                    } else if (colIdx == 1) {
                        names.add(result.stringValue());
                    }
                }
            }
        } finally {
            sa.unaccessData();
        }
        sa.destroy();
    }
    recordset.Close();
    // Requery and fetch only columns "System.ItemUrl", "System.ItemName" and "System.ItemUrl"
    recordset = fact.createObject(Recordset.class);
    recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1);
    // Create SAFEARRAY and wrap it into a VARIANT
    // Array is initialized to one element and then redimmed. This is done
    // to test SafeArrayRedim, in normal usage it is more efficient to 
    // intitialize directly to the correct size
    SAFEARRAY arr = SAFEARRAY.createSafeArray(1);
    arr.putElement(new VARIANT("System.ItemUrl"), 0);
    boolean exceptionCaught = false;
    try {
        arr.putElement(new VARIANT("System.ItemName"), 1);
    } catch (COMException ex) {
        exceptionCaught = true;
    }
    assertTrue("Array is initialized to a size of one - it can't hold a second item.", exceptionCaught);
    arr.redim(2, 0);
    arr.putElement(new VARIANT("System.ItemName"), 1);
    assertThat(arr.getDimensionCount(), is(1));
    VARIANT columnList = new VARIANT();
    columnList.setValue(Variant.VT_ARRAY | Variant.VT_VARIANT, arr);
    assert !(recordset.getEOF());
    while (!recordset.getEOF()) {
        SAFEARRAY sa = recordset.GetRows(5, VARIANT.VARIANT_MISSING, columnList);
        assertThat(sa.getDimensionCount(), is(2));
        assertThat(sa.getVarType().intValue(), is(Variant.VT_VARIANT));
        LONGByReference longRef = new LONGByReference();
        OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(2), longRef);
        int lowerBound = longRef.getValue().intValue();
        assertThat(sa.getLBound(0), equalTo(lowerBound));
        OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(2), longRef);
        int upperBound = longRef.getValue().intValue();
        assertThat(sa.getUBound(0), equalTo(upperBound));
        // 5 rows are expected
        assertThat(upperBound - lowerBound + 1, is(5));
        for (int rowIdx = lowerBound; rowIdx <= upperBound; rowIdx++) {
            VARIANT variantItemUrl = (VARIANT) sa.getElement(rowIdx, 0);
            VARIANT variantItemName = (VARIANT) sa.getElement(rowIdx, 1);
            assertThat(variantItemUrl.stringValue(), is(urls.get(rowIdx)));
            assertThat(variantItemName.stringValue(), is(names.get(rowIdx)));
            OleAuto.INSTANCE.VariantClear(variantItemUrl);
            OleAuto.INSTANCE.VariantClear(variantItemName);
        }
        sa.destroy();
    }
    recordset.Close();
    // Requery and fetch only columns "System.ItemUrl", "System.ItemName" and "System.ItemUrl"
    recordset = fact.createObject(Recordset.class);
    recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1);
    assert !(recordset.getEOF());
    while (!recordset.getEOF()) {
        Object[][] data = (Object[][]) OaIdlUtil.toPrimitiveArray(recordset.GetRows(5, VARIANT.VARIANT_MISSING, columnList), true);
        assertThat(data.length, is(5));
        assertThat(data[0].length, is(2));
        for (int rowIdx = 0; rowIdx < data.length; rowIdx++) {
            assertThat((String) data[rowIdx][0], is(urls.get(rowIdx)));
            assertThat((String) data[rowIdx][1], is(names.get(rowIdx)));
        }
    }
    recordset.Close();
    conn.Close();
    fact.disposeAll();
}
Also used : COMException(com.sun.jna.platform.win32.COM.COMException) SAFEARRAY(com.sun.jna.platform.win32.OaIdl.SAFEARRAY) LONGByReference(com.sun.jna.platform.win32.WinDef.LONGByReference) ArrayList(java.util.ArrayList) Pointer(com.sun.jna.Pointer) VARIANT(com.sun.jna.platform.win32.Variant.VARIANT) IConnectionPoint(com.sun.jna.platform.win32.COM.util.IConnectionPoint) ObjectFactory(com.sun.jna.platform.win32.COM.util.ObjectFactory) ComObject(com.sun.jna.platform.win32.COM.util.annotation.ComObject) UINT(com.sun.jna.platform.win32.WinDef.UINT) VT_UINT(com.sun.jna.platform.win32.Variant.VT_UINT) LONGByReference(com.sun.jna.platform.win32.WinDef.LONGByReference) Test(org.junit.Test)

Example 2 with ObjectFactory

use of com.sun.jna.platform.win32.COM.util.ObjectFactory in project jna by java-native-access.

the class SAFEARRAYTest method testPerformance.

@Ignore("Only for live testing")
@Test
public void testPerformance() {
    ObjectFactory fact = new ObjectFactory();
    // Open a record set with a sample search (basicly get the first five
    // entries from the search index
    Connection conn = fact.createObject(Connection.class);
    conn.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';", "", "", -1);
    Recordset recordset = fact.createObject(Recordset.class);
    recordset.Open("SELECT TOP 500 System.ItemPathDisplay, System.ItemName, System.ItemUrl, System.DateCreated FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1);
    SAFEARRAY wrap = recordset.GetRows();
    assertThat(wrap.getDimensionCount(), is(2));
    long timeDirect = 0;
    long timeGetElement = 0;
    long timePointer = 0;
    long timeHelper = 0;
    long start, end;
    for (int i = 0; i < 4 * 10; i++) {
        if (i % 4 == 0) {
            start = System.currentTimeMillis();
            toArrayPtrToElement(wrap);
            end = System.currentTimeMillis();
            timePointer += (end - start);
        } else if (i % 4 == 1) {
            start = System.currentTimeMillis();
            toArrayGetElement(wrap);
            end = System.currentTimeMillis();
            timeGetElement += (end - start);
        } else if (i % 4 == 2) {
            start = System.currentTimeMillis();
            toArrayDirect(wrap);
            end = System.currentTimeMillis();
            timeDirect += (end - start);
        } else if (i % 4 == 3) {
            start = System.currentTimeMillis();
            OaIdlUtil.toPrimitiveArray(wrap, false);
            end = System.currentTimeMillis();
            timeHelper += (end - start);
        }
    }
    System.out.println("Direct: " + timeDirect + " ms");
    System.out.println("GetElement: " + timeGetElement + " ms");
    System.out.println("Pointer: " + timePointer + " ms");
    System.out.println("Helper: " + timeHelper + " ms");
    recordset.Close();
    conn.Close();
    fact.disposeAll();
}
Also used : ObjectFactory(com.sun.jna.platform.win32.COM.util.ObjectFactory) SAFEARRAY(com.sun.jna.platform.win32.OaIdl.SAFEARRAY) IConnectionPoint(com.sun.jna.platform.win32.COM.util.IConnectionPoint) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 3 with ObjectFactory

use of com.sun.jna.platform.win32.COM.util.ObjectFactory in project jna by java-native-access.

the class Convert method toJavaObject.

public static Object toJavaObject(VARIANT value, Class<?> targetClass, ObjectFactory factory, boolean addReference, boolean freeValue) {
    if (null == value || value.getVarType().intValue() == VT_EMPTY || value.getVarType().intValue() == VT_NULL) {
        return null;
    }
    if (targetClass != null && (!targetClass.isAssignableFrom(Object.class))) {
        if (targetClass.isAssignableFrom(value.getClass())) {
            return value;
        }
        Object vobj = value.getValue();
        if (vobj != null && (targetClass.isAssignableFrom(vobj.getClass()))) {
            return vobj;
        }
    }
    VARIANT inputValue = value;
    if (value.getVarType().intValue() == (VT_BYREF | VT_VARIANT)) {
        value = (VARIANT) value.getValue();
    }
    // handling
    if (targetClass == null || (targetClass.isAssignableFrom(Object.class))) {
        targetClass = null;
        int varType = value.getVarType().intValue();
        switch(value.getVarType().intValue()) {
            case VT_UI1:
            case VT_I1:
            case VT_BYREF | VT_UI1:
            case VT_BYREF | VT_I1:
                targetClass = Byte.class;
                break;
            case VT_I2:
            case VT_BYREF | VT_I2:
                targetClass = Short.class;
                break;
            case VT_UI2:
            case VT_BYREF | VT_UI2:
                targetClass = Character.class;
                break;
            case VT_INT:
            case VT_UINT:
            case VT_UI4:
            case VT_I4:
            case VT_BYREF | VT_I4:
            case VT_BYREF | VT_UI4:
            case VT_BYREF | VT_INT:
            case VT_BYREF | VT_UINT:
                targetClass = Integer.class;
                break;
            case VT_UI8:
            case VT_I8:
            case VT_BYREF | VT_I8:
            case VT_BYREF | VT_UI8:
                targetClass = Long.class;
                break;
            case VT_R4:
            case VT_BYREF | VT_R4:
                targetClass = Float.class;
                break;
            case VT_R8:
            case VT_BYREF | VT_R8:
                targetClass = Double.class;
                break;
            case VT_BOOL:
            case VT_BYREF | VT_BOOL:
                targetClass = Boolean.class;
                break;
            case VT_ERROR:
            case VT_BYREF | VT_ERROR:
                targetClass = WinDef.SCODE.class;
                break;
            case VT_CY:
            case VT_BYREF | VT_CY:
                targetClass = OaIdl.CURRENCY.class;
                break;
            case VT_DATE:
            case VT_BYREF | VT_DATE:
                targetClass = Date.class;
                break;
            case VT_BSTR:
            case VT_BYREF | VT_BSTR:
                targetClass = String.class;
                break;
            case VT_UNKNOWN:
            case VT_BYREF | VT_UNKNOWN:
                targetClass = com.sun.jna.platform.win32.COM.IUnknown.class;
                break;
            case VT_DISPATCH:
            case VT_BYREF | VT_DISPATCH:
                targetClass = IDispatch.class;
                break;
            case VT_BYREF | VT_VARIANT:
                targetClass = Variant.class;
                break;
            case VT_BYREF:
                targetClass = PVOID.class;
                break;
            case VT_BYREF | VT_DECIMAL:
                targetClass = OaIdl.DECIMAL.class;
                break;
            case VT_RECORD:
            default:
                if ((varType & VT_ARRAY) > 0) {
                    targetClass = OaIdl.SAFEARRAY.class;
                }
        }
    }
    Object result;
    if (Byte.class.equals(targetClass) || byte.class.equals(targetClass)) {
        result = value.byteValue();
    } else if (Short.class.equals(targetClass) || short.class.equals(targetClass)) {
        result = value.shortValue();
    } else if (Character.class.equals(targetClass) || char.class.equals(targetClass)) {
        result = (char) value.intValue();
    } else if (Integer.class.equals(targetClass) || int.class.equals(targetClass)) {
        result = value.intValue();
    } else if (Long.class.equals(targetClass) || long.class.equals(targetClass) || IComEnum.class.isAssignableFrom(targetClass)) {
        result = value.longValue();
    } else if (Float.class.equals(targetClass) || float.class.equals(targetClass)) {
        result = value.floatValue();
    } else if (Double.class.equals(targetClass) || double.class.equals(targetClass)) {
        result = value.doubleValue();
    } else if (Boolean.class.equals(targetClass) || boolean.class.equals(targetClass)) {
        result = value.booleanValue();
    } else if (Date.class.equals(targetClass)) {
        result = value.dateValue();
    } else if (String.class.equals(targetClass)) {
        result = value.stringValue();
    } else if (value.getValue() instanceof com.sun.jna.platform.win32.COM.IDispatch) {
        com.sun.jna.platform.win32.COM.IDispatch d = (com.sun.jna.platform.win32.COM.IDispatch) value.getValue();
        Object proxy = factory.createProxy(targetClass, d);
        // call
        if (!addReference) {
            int n = d.Release();
        }
        result = proxy;
    } else {
        /*
                    WinDef.SCODE.class.equals(targetClass) 
                        || OaIdl.CURRENCY.class.equals(targetClass)
                        || OaIdl.DECIMAL.class.equals(targetClass)
                        || OaIdl.SAFEARRAY.class.equals(targetClass)
                        || com.sun.jna.platform.win32.COM.IUnknown.class.equals(targetClass)
                        || Variant.class.equals(targetClass)
                        || PVOID.class.equals(targetClass
                    */
        result = value.getValue();
    }
    if (IComEnum.class.isAssignableFrom(targetClass)) {
        result = targetClass.cast(Convert.toComEnum((Class<? extends IComEnum>) targetClass, result));
    }
    if (freeValue) {
        free(inputValue, result);
    }
    return result;
}
Also used : VARIANT(com.sun.jna.platform.win32.Variant.VARIANT) VT_VARIANT(com.sun.jna.platform.win32.Variant.VT_VARIANT) WinDef(com.sun.jna.platform.win32.WinDef) OaIdl(com.sun.jna.platform.win32.OaIdl)

Example 4 with ObjectFactory

use of com.sun.jna.platform.win32.COM.util.ObjectFactory in project jna by java-native-access.

the class EnumMoniker_Test method before.

@Before
public void before() {
    WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED);
    COMUtils.checkRC(hr);
    this.factory = new ObjectFactory();
    // Two COM objects are require to be running for these tests to work
    this.ob1 = this.factory.createObject(MsWordApp.class);
    this.ob2 = this.factory.createObject(MsWordApp.class);
}
Also used : ObjectFactory(com.sun.jna.platform.win32.COM.util.ObjectFactory) WinNT(com.sun.jna.platform.win32.WinNT) HRESULT(com.sun.jna.platform.win32.WinNT.HRESULT) Before(org.junit.Before)

Aggregations

ObjectFactory (com.sun.jna.platform.win32.COM.util.ObjectFactory)3 IConnectionPoint (com.sun.jna.platform.win32.COM.util.IConnectionPoint)2 SAFEARRAY (com.sun.jna.platform.win32.OaIdl.SAFEARRAY)2 VARIANT (com.sun.jna.platform.win32.Variant.VARIANT)2 Test (org.junit.Test)2 Pointer (com.sun.jna.Pointer)1 COMException (com.sun.jna.platform.win32.COM.COMException)1 ComObject (com.sun.jna.platform.win32.COM.util.annotation.ComObject)1 OaIdl (com.sun.jna.platform.win32.OaIdl)1 VT_UINT (com.sun.jna.platform.win32.Variant.VT_UINT)1 VT_VARIANT (com.sun.jna.platform.win32.Variant.VT_VARIANT)1 WinDef (com.sun.jna.platform.win32.WinDef)1 LONGByReference (com.sun.jna.platform.win32.WinDef.LONGByReference)1 UINT (com.sun.jna.platform.win32.WinDef.UINT)1 WinNT (com.sun.jna.platform.win32.WinNT)1 HRESULT (com.sun.jna.platform.win32.WinNT.HRESULT)1 ArrayList (java.util.ArrayList)1 Before (org.junit.Before)1 Ignore (org.junit.Ignore)1