/** * Constructs a PIM list. * * @param pimList initial list * @param type type of list */ protected AbstractPIMItem(AbstractPIMList pimList, int type) { this.pimList = pimList; this.listType = type; pimHandler = PIMHandler.getInstance(); try { pimListHandle = pimList != null ? pimList.getHandle() : pimHandler.openList(type, null, PIM.READ_ONLY); dummyList = pimList == null; } catch (PIMException e) { e.printStackTrace(); throw new RuntimeException("Error while opening default list"); } }
/** * Filters attributes to include only the supported ones. * * @param field identifier of field * @param attributes field properties * @return filtered attributes */ private int filterAttributes(int field, int attributes) { if (attributes == 0) { return 0; } else { return attributes & pimHandler.getSupportedAttributesMask(pimListHandle, field); } }
/** * Adds a value to a field. * * @param field identifier of field * @param attributes field properties * @param value field to update * @param force if <code>true</code> create the value * @throws FieldFullException if no more values can be added to the field */ private void addValue(int field, int attributes, Object value, boolean force) { checkType(field, value); PIMField pimField = getField(field, true, true); int maxValues = pimHandler.getMaximumValues(pimListHandle, field); int currentValues = pimField.getValueCount(); if (maxValues != -1 && currentValues >= maxValues) { throw new FieldFullException("Can only store " + maxValues + " in field", field); } if (!force) { checkReadOnlyFields(field); } if (value instanceof Integer) { checkIntValue(field, ((Integer) value).intValue()); } if (pimField.isScalar()) { // upgrade PIM field if (currentValues == 0) { pimField = new ScalarPIMField(); putField(field, pimField); } else { Object value0 = pimField.getValue(0); int attributes0 = pimField.getAttributes(0); pimField = new VectorPIMField(); pimField.addValue(attributes0, value0); putField(field, pimField); } } attributes = filterAttributes(field, attributes); pimField.addValue(attributes, value); modified = true; }
/** Sets default values for this item. */ protected void setDefaultValues() { int[] supportedFields = pimList.getSupportedFields(); for (int i = 0; i < supportedFields.length; i++) { int field = supportedFields[i]; PIMField pimField = getField(field, false, true); if ((pimField == null || pimField.getValueCount() == 0) && pimHandler.hasDefaultValue(pimListHandle, field)) { Object value = null; switch (pimList.getFieldDataType(field)) { case PIMItem.BOOLEAN: value = new Boolean(pimHandler.getDefaultBooleanValue(pimListHandle, field)); break; case PIMItem.BINARY: value = pimHandler.getDefaultBinaryValue(pimListHandle, field); break; case PIMItem.DATE: value = new Long(pimHandler.getDefaultDateValue(pimListHandle, field)); break; case PIMItem.INT: value = new Integer(pimHandler.getDefaultIntValue(pimListHandle, field)); break; case PIMItem.STRING: value = pimHandler.getDefaultStringValue(pimListHandle, field); break; case PIMItem.STRING_ARRAY: value = pimHandler.getDefaultStringArrayValue(pimListHandle, field); break; default: continue; } addValue(field, PIMItem.ATTR_NONE, value, false); } } }
/** * Ensures that the given PIM list name is valid. * * @param pimListType CONTACT_LIST, EVENT_LIST or TODO_LIST * @param name name of the list * @throws PIMException if list with the specified name is not found */ private void validateName(int pimListType, String name) throws PIMException { String[] names = PIMHandler.getInstance().getListNames(pimListType); for (int i = 0; i < names.length; i++) { if (name.equals(names[i])) { return; } } throw new PIMException("PIM list does not exist: '" + name + "'"); }
/** * Checks the type of a field, throwing an IllegalArgumentException if given or if the field * number is invalid. * * @param field identifier of field * @param dataType data type for field value */ private void checkType(int field, int dataType) { int correctDataType = pimHandler.getFieldDataType(pimListHandle, field); if (dataType != correctDataType && correctDataType != -1) { throw new IllegalArgumentException("Wrong data type"); } if (correctDataType == -1) { throw complaintAboutField(listType, field); } }
/** Ensures that the underlying list is closed. */ protected void finalize() { if (dummyList) { try { pimHandler.closeList(pimListHandle); } catch (PIMException e) { // Ignore silently } } }
/** * Opens the PIM list. * * @param pimListType CONTACT_LIST, EVENT_LIST or TODO_LIST * @param mode READ_ONLY, WRITE_ONLY or READ_WRITE * @return handle to opened PIM list * @throws PIMException if the list is not found */ public PIMList openPIMList(int pimListType, int mode) throws PIMException { validatePimListType(pimListType); validateMode(mode); checkPermissions(pimListType, mode); String listName = PIMHandler.getInstance().getDefaultListName(pimListType); if (listName == null) { throw new PIMException("List not available"); } return openPIMListImpl(pimListType, mode, listName); }
/** * Makes sure that * * <ul> * <li>The string array is not null * <li>At least one string in the array is not null * <li>The string array has the correct length * </ul> * * @param field identifier for field * @param a string array to be checked */ private void validateStringArray(int field, String[] a) { int requiredLength = pimHandler.getStringArraySize(pimListHandle, field); if (a.length != requiredLength) { throw new IllegalArgumentException( "String array length incorrect: should be " + requiredLength); } for (int i = 0; i < a.length; i++) { if (a[i] != null) { return; } } throw new IllegalArgumentException("No non-null elements in array"); }
/** * Gets the field entry. * * @param field identifier for the field * @param create if <code>true</code> create the field if it doesn't already exist * @param check if <code>true</code> check that the field is supported before attempting to get it * @return the request field entry */ PIMField getField(int field, boolean create, boolean check) { PIMField f = getField(field); if (f == null) { if (check && !pimHandler.isSupportedField(pimListHandle, field)) { throw complaintAboutField(listType, field); } if (create) { f = new EmptyPIMField(); putField(field, f); } } return f; }
// JAVADOC COMMENT ELIDED public void addToCategory(String category) throws PIMException { this.modified = false; if (category == null) { throw new NullPointerException("Null category"); } int maxCategories = maxCategories(); if (maxCategories == 0) { throw new PIMException("Categories are not supported", PIMException.FEATURE_NOT_SUPPORTED); } // Check if the category is in the database String[] listCategories = pimHandler.getCategories(pimListHandle); boolean foundCategory = false; for (int i = 0; i < listCategories.length; i++) { if (category.equals(listCategories[i])) { foundCategory = true; break; } } if (!foundCategory) { throw new PIMException("Category " + category + " is not in list"); } if (categories == null) { this.categories = new String[] {category}; this.modified = true; } else { for (int i = 0; i < categories.length; i++) { if (categories[i].equals(category)) { return; } } // -1 means unlimited number of categories if (maxCategories != -1 && maxCategories <= categories.length) { throw new PIMException("max categories that this item can " + "be assigned to is exceeded"); } String[] a = new String[categories.length + 1]; System.arraycopy(categories, 0, a, 0, categories.length); a[categories.length] = category; this.categories = a; this.modified = true; } }
/** * Checks the type of a field, throwing an IllegalArgumentException if given or if the field * number is invalid. * * @param field identifier for field * @param value data to be checked * @throws IllegalArgumentException if data type is not known */ private void checkType(int field, Object value) { try { int dataType = pimHandler.getFieldDataType(pimListHandle, field); switch (dataType) { case PIMItem.BINARY: { byte[] b = (byte[]) value; break; } case PIMItem.BOOLEAN: { Boolean b = (Boolean) value; break; } case PIMItem.DATE: { Long l = (Long) value; break; } case PIMItem.INT: { Integer i = (Integer) value; break; } case PIMItem.STRING: { String s = (String) value; break; } case PIMItem.STRING_ARRAY: { String[] s = (String[]) value; break; } default: throw complaintAboutField(listType, field); } } catch (ClassCastException cce) { throw new IllegalArgumentException(cce.getMessage()); } }
/** * Does the same as openPIMList, without any validation * * @param pimListType CONTACT_LIST, EVENT_LIST or TODO_LIST * @param mode READ_ONLY, WRITE_ONLY or READ_WRITE * @param name name of the list * @return handle to opened PIM list * @throws PIMException if the list is not found */ private PIMList openPIMListImpl(int pimListType, int mode, String name) throws PIMException { AbstractPIMList list; PIMHandler handler = PIMHandler.getInstance(); Object listHandle = handler.openList(pimListType, name, mode); switch (pimListType) { case PIM.CONTACT_LIST: list = new ContactListImpl(name, mode, listHandle); break; case PIM.EVENT_LIST: list = new EventListImpl(name, mode, listHandle); break; case PIM.TODO_LIST: list = new ToDoListImpl(name, mode, listHandle); break; default: // pimListType has been verified throw new Error("Unreachable code"); } Object[] keys = handler.getListKeys(listHandle); for (int i = 0; i < keys.length; i++) { byte[] data = handler.getListElement(listHandle, keys[i]); String[] categories = handler.getListElementCategories(listHandle, keys[i]); try { PIMItem[] items = fromSerialFormat(new ByteArrayInputStream(data), "UTF-8", list); for (int j = 0; j < items.length; j++) { AbstractPIMItem item = (AbstractPIMItem) items[j]; item.setKey(keys[i]); list.addItem(item); item.setDefaultValues(); for (int index = 0; index < categories.length; index++) { item.addToCategory(categories[index]); } item.setModified(false); } } catch (UnsupportedEncodingException e) { throw new Error("UTF-8 not supported"); } catch (PIMException e) { // skip element } } return list; }
/** * Gets the current PIM lists. * * @param pimListType type of list to return * @return array of list names */ public String[] listPIMLists(int pimListType) { checkPermissions(pimListType, PIM.READ_ONLY); validatePimListType(pimListType); return PIMHandler.getInstance().getListNames(pimListType); }
// JAVADOC COMMENT ELIDED public int maxCategories() { return pimHandler.getMaxCategoriesPerItem(pimListHandle); }
/** * Format the data for output. * * @return formatted data */ protected String formatData() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < fieldValues.length; i++) { if (fieldValues[i].getValueCount() != 0) { PIMField pimField = fieldValues[i]; int field = fieldKeys[i]; int valueCount = pimField.getValueCount(); if (valueCount == 0) { continue; } if (i != 0) { sb.append(", "); } String label = pimHandler.getFieldLabel(pimListHandle, field); int dataType = pimHandler.getFieldDataType(pimListHandle, field); for (int j = 0; j < valueCount; j++) { sb.append(label); if (valueCount != 1) { sb.append("["); sb.append(j); sb.append("]"); } sb.append("="); Object value = pimField.getValue(j); if (value == null) { sb.append("null"); continue; } switch (dataType) { case STRING_ARRAY: { String[] aValue = (String[]) value; sb.append("["); for (int k = 0; k < aValue.length; k++) { if (k != 0) { sb.append(","); } sb.append(aValue[k]); } sb.append("]"); break; } case BINARY: { byte[] bValue = (byte[]) value; sb.append("<" + bValue.length + " bytes>"); break; } case DATE: { long dValue = ((Long) value).longValue(); sb.append(pimHandler.composeDateTime(dValue)); break; } default: sb.append(value); } } } } if (categories != null && categories.length != 0) { if (sb.length() > 0) { sb.append(", "); } sb.append("Categories=["); for (int i = 0; i < categories.length; i++) { if (i > 0) { sb.append(","); } sb.append(categories[i]); } sb.append("]"); } return sb.toString(); }