FileDocCategorySizeDatePackage
BluetoothNotifier.javaAPI DocphoneME MR2 API (J2ME)6771Wed May 02 18:00:32 BST 2007com.sun.kvem.jsr082.bluetooth

BluetoothNotifier.java

/*
 *
 *
 * Copyright  1990-2007 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.kvem.jsr082.bluetooth;

import java.io.IOException;
import javax.microedition.io.Connection;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.ServiceRegistrationException;
import javax.bluetooth.DataElement;
import com.sun.midp.io.BluetoothUrl;
import java.util.Enumeration;

/**
 * Base class for all bluetooth notifiers.
 */
public abstract class BluetoothNotifier implements Connection {

    /** Flag to identify if this notifier is closed. */
    protected boolean isClosed = false;

    /** Bluetooth url this notifier created with. */
    protected BluetoothUrl url;

    /** Service record that describes represented service. */
    protected ServiceRecordImpl serviceRec = null;

    /** Keeps open mode. */
    protected int mode;

    /**
     * Class constructor.
     *
     * @param url server connection string this notifier was created with
     * @param mode I/O access mode
     */
    protected BluetoothNotifier(BluetoothUrl url, int mode) {
        // IMPL_NOTE: find proper place; the intent here is to start EmulationPolling
        // and SDPServer prior to create a user's notifier
        SDDB.getInstance();
        this.url = url;
        this.mode = mode;
    }

    /**
     * Retrieves service record for this notifier.
     * It always returns the same object reference.
     *
     * @return service record associated with this notifier
     * @throws IllegalArgumentException if the notifier is closed
     */
    ServiceRecord getServiceRecord() {
        if (isClosed) {
            throw new IllegalArgumentException("Notifier is closed.");
        }
        // IMPL_NOTE: copy should probably be returned instead of a reference,
        // but the current implementation returns reference to make TCK pass
        // return serviceRec.copy();
        return serviceRec;
    }

    /**
     * Stores the service record for this notifier in the local SDDB.
     * If there is no SDDB version of the service record, this method will
     * do nothing.
     *
     * @param record new service record value
     * @throws IllegalArgumentException if new record is invalid
     *
     * @throws ServiceRegistrationException if the record cannot be
     *         updated successfully in the SDDB
     */
    protected void updateServiceRecord(ServiceRecordImpl record)
            throws ServiceRegistrationException {
        // IMPL_NOTE: the current implementation assumes record and
        // this.serviceRec reference the same object to make TCK pass
        // ServiceRecordImpl oldRecord = serviceRec;
        // serviceRec = record.copy();
        try {
            checkServiceRecord();
        } catch (ServiceRegistrationException e) {
            // serviceRec = oldRecord;
            throw new IllegalArgumentException(e.getMessage());
        }
        if (SDDB.getInstance().contains(serviceRec)) {
            SDDB.getInstance().updateServiceRecord(serviceRec);
        }
    }

    /**
     * Ensures that the service record is valid.
     *
     * @throws ServiceRegistrationException if the structure of the
     *         <code>srvRecord</code> is  missing any mandatory service
     *         attributes, or if an attempt has been made to change any of the
     *         values described as fixed
     */
    protected abstract void checkServiceRecord()
            throws ServiceRegistrationException;

    /**
     * Compares two DataElements.
     *
     * @param first first DataElement
     * @param second second DataElement
     * @return true if elements are equal, false otherwise
     * @see javax.bluetooth.DataElement
     */
    protected boolean compareDataElements(DataElement first,
            DataElement second) {
        boolean ret = false;
        int valueType = first.getDataType();
        if (ret = (valueType == second.getDataType())) {
            switch (valueType) {
            case DataElement.BOOL:
                ret = first.getBoolean() == second.getBoolean();
                break;
            case DataElement.U_INT_1:
            case DataElement.U_INT_2:
            case DataElement.U_INT_4:
            case DataElement.INT_1:
            case DataElement.INT_2:
            case DataElement.INT_4:
            case DataElement.INT_8:
                ret = first.getLong() == second.getLong();
                break;
            default:
                Object v1 = first.getValue();
                Object v2 = second.getValue();
                if (v1 instanceof Enumeration && v2 instanceof Enumeration) {
                    Enumeration e1 = (Enumeration)v1;
                    Enumeration e2 = (Enumeration)v2;
                    ret = true;
                    while (e1.hasMoreElements() &&
                           e2.hasMoreElements() && ret) {
                        ret &= e1.nextElement().equals(e2.nextElement());
                    }
                    ret = ret &&
                        !(e1.hasMoreElements() ||
                          e2.hasMoreElements());
                } else if (v1 instanceof byte[] && v2 instanceof byte[]) {
                    byte[] a1 = (byte[])v1;
                    byte[] a2 = (byte[])v2;
                    ret = a1.length == a2.length;
                    for (int i = a1.length; --i >= 0 && ret; ) {
                        ret &= (a1[i] == a2[i]);
                    }
                } else {
                    ret = v1.equals(v2);
                }
                break;
            }
        }
        return ret;
    }

    /**
     * Closes the connection. <code>Connection</code> interface implementation.
     *
     * @throws IOException if an I/O error occurs
     */
    public abstract void close() throws IOException;
}