/*
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package com.sun.j2me.pim;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import javax.microedition.pim.PIMException;
import javax.microedition.pim.UnsupportedFieldException;
import javax.microedition.pim.PIM;
import com.sun.j2me.main.Configuration;
import com.sun.j2me.pim.formats.FormatSupport;
import com.sun.j2me.jsr75.StringUtil;
/**
* Porting layer implementation for PIM functionality.
*/
public class PIMProxy extends PIMHandler {
/**
* Table of fields for any list.
*/
private Hashtable listFields = new Hashtable();
/**
* Table of attributes for any list.
*/
private Hashtable listAttributes = new Hashtable();
/**
* List handle for which fields have been already initialized.
*/
private Object initialized = null;
/**
* Field for storing data handler between native calls
*/
private int dataHandler;
/**
* Field for storing items counter between native calls
*/
private int itemCounter;
/**
* Constant representing a Contact List.
* List handle for which fields have been already initialized.
*/
public static final int CONTACT_LIST = 1;
/**
* Constant representing an Event List.
*/
public static final int EVENT_LIST = 2;
/**
* Constant representing a ToDo List.
*/
public static final int TODO_LIST = 3;
/**
* This class holds information about a single list.
*/
private static class List {
/** Native handle of the list */
int handle;
/** Type of the list: CONTACT_LIST, EVENT_LIST or TODO_LIST */
int type;
/**
* The only constructor for this list descriptor.
*
* @param listHandle low-level (native) handle of the list
* @param listType CONTACT_LIST, EVENT_LIST or TODO_LIST
*/
List(int listHandle, int listType) {
handle = listHandle;
type = listType;
}
}
/**
* This class holds information about a single list item.
*/
private static class Item {
/** Native handle of the item */
int handle;
/** Binary data of the item */
byte[] rawData;
/** Array of categories the item belongs to */
String[] categories;
/**
* Simple constructor for this item descriptor.
*
* @param list descriptor of the list where the item belongs
* @param handle low-level (native) handle of the item
* @param dataLength size of item's data (in bytes)
*/
Item(int handle, int dataLength) {
this.handle = handle;
rawData = new byte[dataLength];
categories = null;
}
/**
* Constructor that allows to specify categories of the item.
*
* @param list descriptor of the list where the item belongs
* @param handle low-level (native) handle of the item
* @param dataLength size of item's data (in bytes)
* @param cats array of categories the item belongs to
*/
Item(int handle, int dataLength, String[] cats) {
this(handle, dataLength);
setCategories(cats);
}
/**
* Sets categories for the item.
*
* @param cats array of categories the item belongs to
*/
void setCategories(String[] cats) {
categories = cats;
}
/**
* Returns item's categories.
*
* @return array of categories the item belongs to
*/
String[] getCategories() {
String[] cats =
new String[categories == null ? 0 : categories.length];
if (cats.length > 0) {
System.arraycopy(categories, 0, cats, 0, categories.length);
}
return cats;
}
}
/**
* Set up field and attribute descriptions.
*
* @param listHandle descriptor of the list which fields and
* attributes will be retrieved
*/
synchronized private void initialize(Object listHandle) {
if (initialized != listHandle) {
listFields.clear();
listAttributes.clear();
int list = ((List)listHandle).handle;
int [] tmpArray = new int [1];
int numFields = getFieldsCount0(list, tmpArray);
if (numFields <= 0) {
return;
}
PIMFieldDescriptor[] desc = new PIMFieldDescriptor[numFields];
for (int i = 0; i < numFields; i++) {
int numLabels = getFieldLabelsCount0(list, i, tmpArray[0]);
desc[i] = new PIMFieldDescriptor(0, 0, false, null, " ",
new String[numLabels], 0L, 0);
}
getFields0(list, desc, tmpArray[0]);
for (int i = 0; i < numFields; i++) {
listFields.put(new Integer(desc[i].getField()), desc[i]);
}
tmpArray[0] = 0;
int numAttributes = getAttributesCount0(list, tmpArray);
PIMAttribute[] attr = new PIMAttribute[numAttributes];
for (int i = 0; i < numAttributes; i++) {
attr[i] = new PIMAttribute();
}
getAttributes0(list, attr, tmpArray[0]);
for (int i = 0; i < numAttributes; i++) {
listAttributes.put(new Integer(attr[i].getAttr()), attr[i]);
}
initialized = listHandle;
}
}
/**
* Gets the descriptor for given field.
*
* @param field the field ID
*
* @return field descriptor
*/
private PIMFieldDescriptor getFieldDescriptor(int field) {
return (PIMFieldDescriptor)listFields.get(new Integer(field));
}
/**
* Gets all fields that are supported in the given list.
*
* @param listHandle handle of list
* @return an int array containing all supported fields.
*/
public int[] getSupportedFields(Object listHandle) {
initialize(listHandle);
int[] result = new int[listFields.size()];
Enumeration fieldNumbers = listFields.keys();
for (int i = 0; i < result.length; i++) {
result[i] = ((Integer)fieldNumbers.nextElement()).intValue();
}
return result;
}
/**
* Checks if field is supported in list.
* @param listHandle handle of the list
* @param field identifier of field
* @return <code>true</code> if field supported
*/
public boolean isSupportedField(Object listHandle, int field) {
initialize(listHandle);
return getFieldDescriptor(field) != null;
}
/**
* Checks if field has default value.
* @param listHandle handle of the list
* @param field identifier of field
* @return <code>true</code> if field supported
*/
public boolean hasDefaultValue(Object listHandle, int field) {
initialize(listHandle);
return getFieldDescriptor(field).hasDefaultValue();
}
/**
* Gets the data type of the field.
* @param listHandle handle of the list
* @param field identifier of field
* @return data type identifier
*/
public int getFieldDataType(Object listHandle, int field) {
initialize(listHandle);
try {
return getFieldDescriptor(field).getDataType();
} catch (NullPointerException npe) {
return -1;
}
}
/**
* Gets the label of the field.
* @param listHandle handle of the list
* @param field identifier of field
* @return label of the field
*/
public String getFieldLabel(Object listHandle, int field) {
initialize(listHandle);
try {
return getFieldDescriptor(field).getLabel();
} catch (NullPointerException npe) {
return null;
}
}
/**
* Gets the default integer value for the given field. This will
* only
* return a valid value if hasDefaultValue(listType, field) returns true.
* @param listHandle handle of the list
* @param field identifier of field
* @return default value of the field
*/
public int getDefaultIntValue(Object listHandle, int field) {
initialize(listHandle);
PIMFieldDescriptor descriptor = getFieldDescriptor(field);
return ((Integer) descriptor.getDefaultValue()).intValue();
}
/**
* Gets the default string value for the given field. This will
* only
* return a valid value if hasDefaultValue(listType, field) returns true.
* @param listHandle handle of the list
* @param field identifier of field
* @return default value of the field
*/
public String getDefaultStringValue(Object listHandle, int field) {
initialize(listHandle);
return null;
}
/**
* Gets the default String[] value for the given field. This will
* only
* return a valid value if hasDefaultValue(listType, field) returns true.
* @param listHandle handle of the list
* @param field identifier of field
* @return default value of the field
*/
public String[] getDefaultStringArrayValue(Object listHandle, int field) {
int length = getStringArraySize(listHandle, field);
return new String[length];
}
/**
* Gets the default date value for the given field. This will only
* return a valid value if hasDefaultValue(listType, field) returns true.
* @param listHandle handle of the list
* @param field identifier of field
* @return default value of the field
*/
public long getDefaultDateValue(Object listHandle, int field) {
initialize(listHandle);
return 0;
}
/**
* Gets the default byte[] value for the given field. This will
* only
* return a valid value if hasDefaultValue(listType, field) returns true.
* @param listHandle handle of the list
* @param field identifier of field
* @return default value of the field
*/
public byte[] getDefaultBinaryValue(Object listHandle, int field) {
initialize(listHandle);
return null;
}
/**
* Gets the default boolean value for the given field. This will
* only
* return a valid value if hasDefaultValue(listType, field) returns true.
* @param listHandle handle of the list
* @param field identifier of field
* @return default value of the field
*/
public boolean getDefaultBooleanValue(Object listHandle, int field) {
initialize(listHandle);
return false;
}
/**
* Gets the supported attributes for the given field.
* @param listHandle handle of the list
* @param field identifier of field
* @return array of supported attributes of the field
*/
public int[] getSupportedAttributes(Object listHandle, int field) {
initialize(listHandle);
long attributes = getFieldDescriptor(field).getSupportedAttributes();
// ATTR_NONE is supported for all Contact fields
int elementCount = 0;
for (long a = attributes; a > 0; a >>= 1) {
if ((a & 1) == 1) {
elementCount++;
}
}
int[] result = new int[elementCount];
if (elementCount > 0) {
int a = 1;
for (int i = 0; i < elementCount; i++) {
while ((attributes & a) == 0) a <<= 1;
result[i] = a;
a <<= 1;
}
}
return result;
}
/**
* Gets a mask containing all possible attributes for the given field.
*
* @param listHandle handle of the list
* @param field the field number
* @return supported attribute mask
*/
public int getSupportedAttributesMask(Object listHandle, int field) {
initialize(listHandle);
return (int)getFieldDescriptor(field).getSupportedAttributes();
}
/**
* Gets attribute label for the given field attribute.
*
* @param listHandle handle of the list
* @param attribute identifier of attribute
* @return attribute label
*/
public String getAttributeLabel(Object listHandle, int attribute) {
initialize(listHandle);
if (attribute == PIMItem.ATTR_NONE) {
String tag = "PIM.Attributes.None";
String ret = Configuration.getProperty(tag);
return ret == null ? "Label_" + tag : ret;
}
try {
return ((PIMAttribute)listAttributes.
get(new Integer(attribute))).getLabel();
} catch (NullPointerException npe) {
throw new UnsupportedFieldException("Attribute " + attribute +
" is not supported");
}
}
/**
* Checks if attribute is supported.
*
* @param listHandle handle of the list
* @param field the field number
* @param attribute identifier of attribute
* @return <code>true</code> if attribute is supported
*/
public boolean isSupportedAttribute(Object listHandle, int field,
int attribute) {
initialize(listHandle);
if (attribute == PIMItem.ATTR_NONE) {
return true;
} else {
long attributes = getFieldDescriptor(field).
getSupportedAttributes();
return (attributes & attribute) != 0;
}
}
/**
* Checks if size of the string array.
*
* @param listHandle handle of the list
* @param field the field number
* @return size of the string array
*/
public int getStringArraySize(Object listHandle, int field) {
initialize(listHandle);
try {
return getFieldDescriptor(field).getStringArraySize();
} catch (NullPointerException e) {
// debug.exception(Debug.LIGHT, e);
return 0;
}
}
/**
* Gets the array of supported elements.
*
* @param listHandle handle of the list
* @param field the field number
* @return array of supported elements
*/
public int[] getSupportedArrayElements(Object listHandle, int field) {
int size = getStringArraySize(listHandle, field);
int[] result = new int[size];
for (int i = 0; i < size; i++) {
result[i] = i;
}
return result;
}
/**
* Gets the array element label.
*
* @param listHandle handle of the list
* @param field the field number
* @param arrayElement the element identifier
* @return label fro the array element
*/
public String getArrayElementLabel(Object listHandle, int field,
int arrayElement) {
initialize(listHandle);
return getFieldDescriptor(field).getElementlabel(arrayElement);
}
/**
* Checks if the array element is supported.
*
* @param listHandle handle of the list
* @param field the field number
* @param arrayElement the element identifier
* @return <code>true</code> if attribute element is supported
*/
public boolean isSupportedArrayElement(Object listHandle, int field,
int arrayElement) {
return arrayElement >= 0 &&
arrayElement < getStringArraySize(listHandle, field);
}
/**
* Get the maximum number of values that can be stored in the given field.
*
* @param listHandle handle of the list
* @param field the field type
* @return the maximum value
*/
public int getMaximumValues(Object listHandle, int field) {
initialize(listHandle);
return getFieldDescriptor(field).getMaximumValues();
}
/**
* Get the supported list names for the given list type. All list elements
* must be unique within the list.
*
* @param listType the type of the list
* @return a non-null array of supported list names. A copy of this array is
* returned by PIM.listPIMLists()
*/
synchronized public String[] getListNames(int listType) {
int namesCount = getListNamesCount0(listType);
String[] listNames = new String[namesCount];
if (namesCount != 0) {
getListNames0(listNames);
}
return listNames;
}
/**
* Opens list.
*
* @param listType the type of the list
* @param listName the name of the list
* @param openMode open mode:
* <ul>
* <li> {@link javax.microedition.pim.PIM#READ_ONLY}
* <li> {@link javax.microedition.pim.PIM#WRITE_ONLY}
* <li> {@link javax.microedition.pim.PIM#READ_WRITE}
* </ul>
* @return list handle that will be used to access this list
* @throws PIMException in case of I/O error.
*/
public Object openList(int listType, String listName, int openMode)
throws PIMException {
int listHandle = listOpen0(listType, listName, openMode);
if (listHandle == 0) {
throw new PIMException("Unable to open list");
}
return new List(listHandle, listType);
}
/**
* Closes list.
*
* @param listHandle handle of list
* @throws PIMException in case of I/O error.
*/
public void closeList(Object listHandle)
throws PIMException {
if (!listClose0(((List)listHandle).handle)) {
throw new PIMException();
}
}
/**
* Get list element keys.
*
* @param listHandle handle of the list
* @return an array of objects representing PIM element keys. These keys
* are to be passed to getListElement() and commitListElement().
* @throws PIMException in case of I/O error.
*/
synchronized public Object[] getListKeys(Object listHandle)
throws PIMException {
Vector keys = new Vector();
int[] itemDesc = new int[4];
int handle = ((List)listHandle).handle;
while (getNextItemDescription0(handle, itemDesc)) {
Item nextItem = new Item(itemDesc[0], itemDesc[1]);
getNextItemData0(nextItem.handle, nextItem.rawData, itemDesc[3]);
keys.addElement(nextItem);
String catList = getItemCategories0(nextItem.handle, itemDesc[3]);
if (catList != null) {
nextItem.setCategories(StringUtil.split(catList, ',', 0));
}
}
Item[] items = new Item[keys.size()];
for (int index = 0; index < items.length; index++) {
items[index] = (Item)keys.elementAt(index);
}
return items;
}
/**
* Get the data for a list element.
* @param listHandle handle of the list
* @param elementKey the key of the requested element
* @return a byte array containing the element data in a supported format
* @throws PIMException in case of I/O error.
*/
public byte[] getListElement(Object listHandle,
Object elementKey) throws PIMException {
return ((Item)elementKey).rawData;
}
/**
* Get categories for the specified list element.
* @param listHandle handle of list
* @param elementKey the key of the requested element
* @return an array of categories names
* @throws PIMException in case of I/O error.
*/
public String[] getListElementCategories(Object listHandle,
Object elementKey) throws PIMException {
return ((Item)elementKey).getCategories();
}
/**
* Commit a list element.
*
* @param listHandle handle of the list
* @param elementKey the key of the element to be stored, or null if this
* is a new element.
* @param element element data in a form that can be interpreted
* by getListElement()
* @param categories list of categories which the list element belongs to
* @return a non-null key for this element, to be used in future calls
* to commitListElement() and getListElement()
* @throws PIMException in case of I/O error.
*/
synchronized public Object commitListElement(Object listHandle,
Object elementKey,
byte[] element,
String[] categories) throws PIMException {
Item item = (Item)elementKey;
List list = (List)listHandle;
if (elementKey == null) {
/* Add new item */
int itemHandle = addItem0(list.handle, element, categories == null ?
null : StringUtil.join(categories, ","));
if (itemHandle == 0) {
throw new PIMException("Unable to add new item");
}
item = new Item(itemHandle, element.length, categories);
item.rawData = element;
} else if (element == null) {
/* Remove item */
if (!removeItem0(list.handle, item.handle)) {
throw new PIMException("Unable to delete item");
}
} else {
item.rawData = element;
if (!commitItemData0(list.handle, item.handle,
element, categories == null ?
null : StringUtil.join(categories, ","))) {
throw new PIMException("Unable to update",
PIMException.UPDATE_ERROR);
}
}
return item;
}
/**
* Gets the set of categories defined for a list.
*
* @param listHandle handle of the list
* @return the set of defined categories
* @throws PIMException If an error occurs or
* the list is no longer accessible or closed.
*/
public String[] getCategories(Object listHandle)
throws PIMException {
String categories = getListCategories0(((List)listHandle).handle);
return categories != null ? StringUtil.split(categories, ',', 0) :
new String[0];
}
/**
* Gets the maximum number of categories this list can have.
*
* @param listHandle handle to the list
* @return the number of categories supported by this list.
* 0 indicates no category support and -1 indicates there is no
* limit for the number of categories that this list can have
*/
public int getMaxCategories(Object listHandle) {
return getListMaxCategories0(((List)listHandle).handle);
}
/**
* Gets the maximum number of categories a list's item can be assigned to.
*
* @param listHandle handle to the list
* @return the number of categories an item can be assigned to.
* 0 indicates no category support and -1 indicates there is no
* limit for the number of categories an item can be assigned to
*/
public int getMaxCategoriesPerItem(Object listHandle) {
return getListMaxCategoriesPerItem0(((List)listHandle).handle);
}
/**
* Adds a category to the categories defined for a list.
*
* @param listHandle handle of list
* @param category category name
* @throws PIMException If an error occurs or
* the list is no longer accessible or closed.
* @see #getCategories
*/
public void addCategory(Object listHandle,
String category) throws PIMException {
if (getCategories(listHandle).length ==
getListMaxCategories0(((List)listHandle).handle)) {
throw new PIMException("Maximum number of categories exceeded",
PIMException.MAX_CATEGORIES_EXCEEDED);
}
if (!addListCategory0(((List)listHandle).handle, category)) {
throw new PIMException("Unable to add category",
PIMException.UPDATE_ERROR);
}
}
/**
* Deletes a category from the categories defined for a list.
*
* @param listHandle handle of list
* @param category category name
* @throws PIMException If an error occurs or
* the list is no longer accessible or closed.
* @see #getCategories
*/
public void deleteCategory(Object listHandle,
String category) throws PIMException {
if (!deleteListCategory0(((List)listHandle).handle, category)) {
throw new PIMException("Unable to delete category",
PIMException.UPDATE_ERROR);
}
}
/**
* Rename a category.
*
* @param listHandle handle of list
* @param currentCategory current category name
* @param newCategory new category name
* @throws PIMException If an error occurs or
* the list is no longer accessible or closed.
* @see #getCategories
*/
public void renameCategory(Object listHandle,
String currentCategory, String newCategory) throws PIMException {
if (!renameListCategory0(((List)listHandle).handle, currentCategory,
newCategory)) {
throw new PIMException("Unable to rename category",
PIMException.UPDATE_ERROR);
}
}
/**
* Returns number of lists of the specified type.
*
* @param listType CONTACT_LIST, EVENT_LIST or TODO_LIST
*
* @return number of lists
* @see #getListNames0
*/
private native int getListNamesCount0(int listType);
/**
* Retrieves list names for the selected list type.
*
* @param names array where list names will be stored
* (must have sufficient number of elements for list names)
* @see #getListNamesCount0
*/
private native void getListNames0(String[] names);
/**
* Get the name of the default list for the given type.
*
* @param listType the type of the list
* @return the name of the default list, or null if no list of this type
* is supported.
*/
public native String getDefaultListName(int listType);
/**
* Opens the specified list.
*
* @param listType CONTACT_LIST, EVENT_LIST or TODO_LIST
* @param listName name of the list to open
* @param mode open mode:
* <ul>
* <li> {@link javax.microedition.pim.PIM#READ_ONLY}
* <li> {@link javax.microedition.pim.PIM#WRITE_ONLY}
* <li> {@link javax.microedition.pim.PIM#READ_WRITE}
* </ul>
*
* @return native handle of the opened list
* @see #listClose0
*/
private native int listOpen0(int listType, String listName, int mode);
/**
* Closes the specified list.
*
* @param listHandle native handle of the list that was previously opened
*
* @return <code>true</code> on success, <code>false</code> otherwise
* @see #listOpen0
*/
private native boolean listClose0(int listHandle);
/**
* Retrieves general information about the next item in the list.
*
* @param listHandle native handle of the list that was previously opened
* @param description buffer to store the item description
*
* @return <code>true</code> on success, <code>false</code> otherwise
*/
private native boolean getNextItemDescription0(int listHandle,
int[] description);
/**
* Retrieves next item's data from the list.
*
* @param itemHandle native handle of the item
* @param data buffer to store the item's data
* @param dataHandle handle for data buffer
* @return <code>true</code> on success, <code>false</code> otherwise
*/
private native boolean getNextItemData0(int itemHandle, byte[] data, int dataHandle);
/**
* Writes modified item data to persistent storage.
*
* @param listHandle native handle of the list that was previously opened
* @param itemHandle native handle of the item
* @param data raw data of the item
* @param categories item's categories, separated by comma
*
* @return <code>true</code> on success, <code>false</code> otherwise
*/
private native boolean commitItemData0(int listHandle, int itemHandle,
byte[] data, String categories);
/**
* Adds item to the list.
*
* @param listHandle native handle of the list that was previously opened
* @param data raw data of the item
* @param categories item's categories, separated by comma
*
* @return native handle of the item
*/
private native int addItem0(int listHandle, byte[] data, String categories);
/**
* Removes specified item from the list.
*
* @param listHandle native handle of the list that was previously opened
* @param itemHandle native handle of the item
*
* @return <code>true</code> on success, <code>false</code> otherwise
*/
private native boolean removeItem0(int listHandle, int itemHandle);
/**
* Retrieves categories defined for the specified list.
*
* @param listHandle native handle of the list that was previously opened
*
* @return item's categories, separated by comma
*/
private native String getListCategories0(int listHandle);
/**
* Returns maximum number of categories supported for the given list.
*
* @param listHandle native handle of the list that was previously opened
*
* @return maximum number of categories for the list
*/
private native int getListMaxCategories0(int listHandle);
/**
* Returns maximum number of categories per item supported for the given
* list.
*
* @param listHandle native handle of the list that was previously opened
*
* @return maximum number of categories per item in the list
*/
private native int getListMaxCategoriesPerItem0(int listHandle);
/**
* Adds category to the specified list.
*
* @param listHandle native handle of the list that was previously opened
* @param category name of the category to add
*
* @return <code>true</code> on success, <code>false</code> otherwise
*/
private native boolean addListCategory0(int listHandle, String category);
/**
* Removes category from the specified list.
*
* @param listHandle native handle of the list that was previously opened
* @param category name of the category to delete
*
* @return <code>true</code> on success, <code>false</code> otherwise
*/
private native boolean deleteListCategory0(int listHandle, String category);
/**
* Renames category supported by the given list.
*
* @param listHandle native handle of the list that was previously opened
* @param currentCategory old category name
* @param newCategory new category name
*
* @return <code>true</code> on success, <code>false</code> otherwise
*/
private native boolean renameListCategory0(int listHandle,
String currentCategory, String newCategory);
/**
* Retrieves list of categories the specified item belongs to.
*
* @param itemHandle native handle of the item
* @param dataHandle handle for data buffer
* @return item's categories, separated by comma
*/
private native String getItemCategories0(int itemHandle, int dataHandle);
/**
* Returns number of fields supported by the given list.
*
* @param listHandle native handle of the list that was previously opened
* @param dataHandle to save data handle in
*
* @return number of supported fields
*/
private native int getFieldsCount0(int listHandle, int [] dataHandle);
/**
* Returns number of labels for the specified field.
*
* @param listHandle native handle of the list that was previously opened
* @param fieldIndex index of the field
* @param dataHandle handle of data
*
* @return number of labels
*/
private native int getFieldLabelsCount0(int listHandle, int fieldIndex, int dataHandle);
/**
* Retrieves information about all fields supported by the list.
*
* @param listHandle native handle of the list that was previously opened
* @param desc array where field descriptions will be stored
* @param dataHandle handle of data
*/
private native void getFields0(int listHandle, PIMFieldDescriptor[] desc, int dataHandle);
/**
* Returns number of attributes supported by the given list.
*
* @param listHandle native handle of the list that was previously opened
*
* @param dataHandle array to store data handle in
* @return number of supported attributes
*/
private native int getAttributesCount0(int listHandle, int[] dataHandle);
/**
* Retrieves information about all attributes supported by the list.
*
* @param listHandle native handle of the list that was previously opened
* @param attr array where attribute descriptions will be stored
* @param dataHandle data handle
*/
private native void getAttributes0(int listHandle, PIMAttribute[] attr, int dataHandle);
}