Search in sources :

Example 1 with SerializedFile

use of dev.hawala.xns.level4.filing.FilingCommon.SerializedFile in project dodo by devhawala.

the class MailingNewImpl method inbasket2_getNextMail.

private static void inbasket2_getNextMail(GetNextMailParams params, GetNextMailResults results) {
    // logging callback used before returning
    UnaryOperator<String> retlog = m -> {
        if (logParamsAndResults) {
            if (m == null) {
                m = "";
            }
            StringBuilder sb = new StringBuilder();
            results.append(sb, "  ", "results");
            logf("##\n## procedure MailingNewImpl.inbasket2_getNextMail() %s -- results\n%s\n##\n", m, sb.toString());
        }
        return null;
    };
    // log ingoing data
    if (logParamsAndResults) {
        StringBuilder sb = new StringBuilder();
        params.append(sb, "  ", "params");
        logf("##\n## procedure MailingNewImpl.inbasket2_getNextMail() -- params\n%s\n##\n", sb.toString());
    }
    // get the session (we do not check the verifier, as we trust our clients...)
    dlogf("  ... fetching mail session ...");
    MailSession session = mailService.getSession(params.sessionId.get());
    if (session == null) {
        logf("failed (invalid session id)\n");
        retlog.apply("[invalid mail session]");
        return;
    }
    // check for valid index for the mail in the inbox
    MailData prevMailData = session.getClientData();
    int index = (prevMailData == null) ? 0 : prevMailData.mailboxIndex + 1;
    dlogf("  ... mailIndex: %d\n", index);
    if (index >= session.getMailCount() || index < 0) {
        // not or no longer present => return empty results
        retlog.apply("[no more mails available]");
        return;
    }
    // get the mail content
    dlogf("  ... getting mailbox entry ... ");
    MailboxEntry me = session.getMailEntry(index);
    dlogf("%s\n", (me != null) ? "ok" : "failed (null)");
    if (me == null) {
        // not or no longer present => return empty results
        retlog.apply("[mail already deleted]");
        return;
    }
    dlogf("  ... loading mail content file ... ");
    ByteArrayOutputStream mailBos = new ByteArrayOutputStream();
    try {
        me.transferContent(istream -> {
            byte[] buffer = new byte[512];
            try {
                int count = istream.read(buffer);
                while (count > 0) {
                    mailBos.write(buffer, 0, count);
                    count = istream.read(buffer);
                }
            } catch (IOException e) {
            // ignore that for now
            }
        });
    } catch (IOException e) {
        // we must at least be able to read the mail file, so...
        retlog.apply("[unable to read mail content]");
        return;
    }
    byte[] mailContentBytes = mailBos.toByteArray();
    dlogf("%d bytes\n", mailContentBytes.length);
    // extract the relevant fields from the (old format) mail content
    dlogf("  ... deserializing mail content ... ");
    SerializedFile mailContentFile = SerializedFile.make();
    try {
        mailContentFile.deserialize(new ByteArrayWireInputStream(mailContentBytes));
    } catch (EndOfMessageException e) {
        // invalid mail file content??
        retlog.apply("[invalid mail file content]");
        return;
    }
    dlogf("ok\n");
    dlogf("  ... extracting relevant data\n");
    NameList xfrom = null;
    NameList xto = null;
    NameList xcc = null;
    NameList xreplyTo = null;
    STRING xsubject = null;
    STRING mailText = null;
    boolean xisFolderAttachment = false;
    SEQUENCE<Attribute> attrs = mailContentFile.file.attributes.value;
    for (int i = 0; i < attrs.size(); i++) {
        try {
            Attribute attr = attrs.get(i);
            int attributeType = (int) (attr.type.get() & 0xFFFF_FFFFL);
            switch(attributeType) {
                case MailingCommon.from:
                    xfrom = attr.decodeData(NameList::make);
                    dlogf("    ... found from\n");
                    break;
                case MailingCommon.to:
                    xto = attr.decodeData(NameList::make);
                    dlogf("    ... found to\n");
                    break;
                case MailingCommon.cc:
                    xcc = attr.decodeData(NameList::make);
                    dlogf("    ... found cc\n");
                    break;
                case MailingCommon.replyTo:
                    xreplyTo = attr.decodeData(NameList::make);
                    dlogf("    ... found replyTo\n");
                    break;
                case MailingCommon.subject:
                    xsubject = attr.decodeData(STRING::make);
                    dlogf("    ... found subject\n");
                    break;
                case MailingCommon.comments:
                    mailText = attr.decodeData(STRING::make);
                    dlogf("    ... found comments\n");
                    break;
                case FilingCommon.atIsDirectory:
                    xisFolderAttachment = attr.getAsBoolean();
                    dlogf("    ... found isDirectory\n");
                    break;
            }
        } catch (EndOfMessageException e) {
            // invalid mail file content??
            retlog.apply("[unable to extract attribute mail file content]");
            return;
        }
    }
    dlogf("  ... done extracting mail content data\n");
    if (xfrom == null || xfrom.size() == 0 || xto == null || xto.size() == 0) {
        retlog.apply("[missing one of from, to]");
        return;
    }
    // extract the relevant fields from the (old format) mail envelope
    dlogf("  ... loading old-format envelope ... ");
    ByteArrayOutputStream envBos = new ByteArrayOutputStream();
    try {
        me.transferPostboxEnvelope(istream -> {
            byte[] buffer = new byte[512];
            try {
                int count = istream.read(buffer);
                while (count > 0) {
                    envBos.write(buffer, 0, count);
                    count = istream.read(buffer);
                }
            } catch (IOException e) {
            // ignore that for now
            }
        });
    } catch (IOException e) {
        // we must at least be able to read the mail envelope, so...
        retlog.apply("[unable to read mail envelope]");
        return;
    }
    byte[] oldEnvelopeBytes = envBos.toByteArray();
    dlogf("ok -> %d bytes\n", oldEnvelopeBytes.length);
    dlogf("  ... deserializing old-format envelope ... ");
    EncodedList oldEnvelope = EncodedList.make();
    try {
        oldEnvelope.deserialize(new ByteArrayWireInputStream(oldEnvelopeBytes));
    } catch (EndOfMessageException e) {
        // invalid mail file envelope??
        retlog.apply("[invalid mail file envelope]");
        return;
    }
    dlogf("ok\n");
    StringBuilder envSb = new StringBuilder();
    oldEnvelope.append(envSb, "  ", "old-envelope");
    dlogf("+++ %s\n", envSb.toString());
    dlogf("  ... extracting mail-id ... ");
    MessageID xmailId = null;
    for (int i = 0; i < oldEnvelope.size(); i++) {
        Attribute attr = oldEnvelope.get(i);
        if (attr.type.get() == MailingCommon.atMtMessageID) {
            try {
                xmailId = attr.decodeData(MessageID::make);
            } catch (EndOfMessageException e) {
                // invalid mail file envelope??
                retlog.apply("[cannot decode messageId from mail file envelope]");
                return;
            }
        }
    }
    if (xmailId == null) {
        // invalid mail file envelope??
        retlog.apply("[invalid mail file envelope]");
        return;
    }
    dlogf("ok\n");
    MessageID mailId = xmailId;
    // synthesize a new format envelope from the old format mail data
    dlogf("  ... creating new-format envelope\n");
    NameList from = xfrom;
    NameList to = xto;
    NameList cc = xcc;
    NameList replyTo = xreplyTo;
    STRING subject = (xsubject == null) ? STRING.make() : xsubject;
    boolean isFolderAttachment = xisFolderAttachment;
    // long mailCreatedOn = me.inboxEntry().getCreatedOn();
    SEQUENCE<Attribute> newEnvelope = new SEQUENCE<>(Attribute::make);
    newEnvelope.add().set(MailTransport5.atSenderAndDate, ThreePartNameWithTagAndDateString::make, v -> {
        v.nameWithTag.name.from(from.get(0));
        // check where this thing possibly re-appears in GlobalView and if so implement as non-constant
        v.date.set("24-Jan-94 21:40:54");
    });
    newEnvelope.add().set(MailTransport5.atSenderA, ThreePartNameWithTag::make, v -> {
        v.name.from(from.get(0));
    });
    newEnvelope.add().set(MailTransport5.atSenderB, ListOfThreePartNameWithTag::make, v -> {
        copyNames(from, v);
    });
    newEnvelope.add().set(MailTransport5.atTo, ListOfThreePartNameWithTag::make, v -> {
        copyNames(to, v);
    });
    if (cc != null && cc.size() > 0) {
        newEnvelope.add().set(MailTransport5.atCopiesTo, ListOfThreePartNameWithTag::make, v -> {
            copyNames(cc, v);
        });
    }
    if (replyTo != null && replyTo.size() > 0) {
        newEnvelope.add().set(MailTransport5.atReplyTo, ListOfThreePartNameWithTag::make, v -> {
            copyNames(replyTo, v);
        });
    }
    newEnvelope.add().set(MailTransport5.atSubject, STRING::make, v -> v.set(subject));
    dlogf("  ... done\n");
    // prepare the temp object holding the contents data to be delivered later
    // and create the serialized data for later use
    MailData mailData = new MailData(((long) session.getSessionId() & 0x0000_0000_FFFF_FFFFL) + index, index);
    dlogf("  ... serializing new-format envelope ...");
    WireWriter wireWriter = new WireWriter();
    try {
        newEnvelope.serialize(wireWriter);
    } catch (NoMoreWriteSpaceException e) {
    // should never happen => ignore
    }
    mailData.envelopeBytes = wireWriter.getBytes();
    dlogf("ok, %d bytes\n", mailData.envelopeBytes.length);
    if (mailText != null && mailText.get() != null) {
        dlogf("  ... creating mail-text (comments) bytes ... ");
        wireWriter = new WireWriter();
        try {
            mailText.serialize(wireWriter);
        } catch (NoMoreWriteSpaceException e) {
        // should never happen => ignore
        }
        // skip the length word
        byte[] mailtextBytes = wireWriter.getBytes(2);
        if (mailtextBytes.length > 0) {
            if (mailtextBytes[mailtextBytes.length - 1] == 0x00) {
                mailtextBytes[mailtextBytes.length - 1] = ' ';
            }
            mailData.mailtextBytes = mailtextBytes;
            dlogf("ok, %d bytes\n", mailData.mailtextBytes.length);
        } else {
            dlogf(" empty mail-text, mail part NOT created\n");
        }
    }
    if (mailContentFile.file.content.data.size() > 0 || xisFolderAttachment) {
        mailData.attachmentBytes = mailContentBytes;
        dlogf("  ... added mail attachment, %d bytes\n", mailData.attachmentBytes.length);
    }
    // prepare the mailInfo-Attributes in the return object
    dlogf("  ... building mail-infos for return data\n");
    dlogf("    ... miMailServer ... ");
    results.mailInfos.value.add().set(Inbasket2.miMailServer, MiMailServer::make, v -> {
        v.name.from(mailService.getServiceName());
        // obscure ...
        v.unknown1.set(0xA926);
        // ... constants?
        v.unknown2.set(0xEB6D);
    });
    dlogf("ok\n");
    dlogf("    ... miMessageId ... ");
    results.mailInfos.value.add().set(Inbasket2.miMessageId, MailingCommon.MessageID::make, v -> {
        for (int i = 0; i < 5; i++) {
            v.get(i).set(mailId.get(i).get());
        }
    });
    dlogf("ok\n");
    dlogf("    ... miWhatever ... ");
    results.mailInfos.value.add().set(Inbasket2.miWhatever, MiWhatever::make, v -> {
        v.value.set(4);
    });
    dlogf("ok\n");
    dlogf("    ... miMailparts ... ");
    long[] lengthSum = { 0 };
    results.mailInfos.value.add().set(Inbasket2.miMailparts, MiMailParts::make, v -> {
        // envelope (always present)
        MiMailPart envPart = v.add();
        envPart.mailPartType.set(MailTransport5.mptEnvelope);
        envPart.mailPartLength.set(mailData.envelopeBytes.length);
        lengthSum[0] = mailData.envelopeBytes.length;
        mailData.parts.add(mailData.envelopeBytes);
        dlogf("envelope ");
        // having mail-text?
        if (mailData.mailtextBytes != null) {
            MiMailPart mailTextPart = v.add();
            mailTextPart.mailPartType.set(MailTransport5.mptNoteGV);
            mailTextPart.mailPartLength.set(mailData.mailtextBytes.length);
            lengthSum[0] += mailData.mailtextBytes.length;
            mailData.parts.add(mailData.mailtextBytes);
            dlogf("noteGV ");
        }
        // having mail-attachment?
        if (mailData.attachmentBytes != null) {
            MiMailPart mailTextPart = v.add();
            mailTextPart.mailPartType.set(isFolderAttachment ? MailTransport5.mptAttachmentFolder : 4);
            mailTextPart.mailPartLength.set(mailData.attachmentBytes.length);
            lengthSum[0] += mailData.attachmentBytes.length;
            mailData.parts.add(mailData.attachmentBytes);
            dlogf("attachment(%d) ", mailTextPart.mailPartType.get());
        }
    });
    dlogf("... ok\n");
    dlogf("    ... miTotalPartsLength ... ");
    results.mailInfos.value.add().set(Inbasket2.miTotalPartsLength, MiTotalPartsLength::make, v -> {
        v.totalLength.set(lengthSum[0]);
    });
    dlogf("ok\n");
    dlogf("    ... miUser0 ... ");
    results.mailInfos.value.add().set(Inbasket2.miSender0, MiSender::make, v -> {
        v.senderName.from(from.get(0));
    });
    dlogf("ok\n");
    dlogf("    ... miUser1 ... ");
    results.mailInfos.value.add().set(Inbasket2.miSender1, MiSender::make, v -> {
        v.senderName.from(from.get(0));
    });
    dlogf("ok\n");
    dlogf("  ... done\n");
    // fill the obscure array values in the return data
    dlogf("  ... adding obscure array ... ");
    if (mailData.mailtextBytes != null && mailData.attachmentBytes != null) {
        // all 3 mail parts
        int[] vals = { 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001 };
        for (int i = 0; i < vals.length; i++) {
            results.unknownSeq.add().set(vals[i]);
        }
    } else if (mailData.mailtextBytes == null && mailData.attachmentBytes == null) {
        // only 1 mail part (envelope)
        int[] vals = { 0x0000, 0x0001, 0x0000, 0x0000 };
        for (int i = 0; i < vals.length; i++) {
            results.unknownSeq.add().set(vals[i]);
        }
    } else {
        // 2 mail parts (envelope and mail-text or attachment)
        int[] vals = { 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
        for (int i = 0; i < vals.length; i++) {
            results.unknownSeq.add().set(vals[i]);
        }
    }
    dlogf("%d words\n", results.unknownSeq.size());
    // done: remember the data container with the mail-parts for later transfer and add the id to the returned data
    session.setClientData(mailData);
    results.uniqueMailNo.set(mailData.mailTransferId);
    dlogf("  ... uniqueMailNo: 0x%08X\n", results.uniqueMailNo.get());
    // log outgoing data
    retlog.apply(null);
}
Also used : SEQUENCE(dev.hawala.xns.level3.courier.SEQUENCE) PostMailPartParams(dev.hawala.xns.level4.mailing.MailTransport5.PostMailPartParams) NameList(dev.hawala.xns.level4.mailing.MailingCommon.NameList) ServerPollResults(dev.hawala.xns.level4.mailing.MailTransport5.ServerPollResults) Time(dev.hawala.xns.level4.common.Time2.Time) MiSender(dev.hawala.xns.level4.mailing.Inbasket2.MiSender) ThreePartNameWithTagAndDateString(dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTagAndDateString) AccessProblem(dev.hawala.xns.level4.mailing.MailingCommon.AccessProblem) UnaryOperator(java.util.function.UnaryOperator) EncodedList(dev.hawala.xns.level4.mailing.MailingCommon.EncodedList) Map(java.util.Map) MiTotalPartsLength(dev.hawala.xns.level4.mailing.Inbasket2.MiTotalPartsLength) ServiceProblem(dev.hawala.xns.level4.mailing.MailingCommon.ServiceProblem) GetNextMailResults(dev.hawala.xns.level4.mailing.Inbasket2.GetNextMailResults) InbasketPollResults(dev.hawala.xns.level4.mailing.Inbasket2.InbasketPollResults) Credentials(dev.hawala.xns.level4.common.AuthChsCommon.Credentials) ErrorRECORD(dev.hawala.xns.level3.courier.ErrorRECORD) ListOfThreePartNameWithTag(dev.hawala.xns.level4.mailing.MailTransport5.ListOfThreePartNameWithTag) Attribute(dev.hawala.xns.level4.filing.FilingCommon.Attribute) LogonParams(dev.hawala.xns.level4.mailing.Inbasket2.LogonParams) NoMoreWriteSpaceException(dev.hawala.xns.level3.courier.iWireStream.NoMoreWriteSpaceException) PostBeginResults(dev.hawala.xns.level4.mailing.MailTransport5.PostBeginResults) dev.hawala.xns.level3.courier.iWireData(dev.hawala.xns.level3.courier.iWireData) EndOfMessageException(dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException) HandleMailPartsParams(dev.hawala.xns.level4.mailing.Inbasket2.HandleMailPartsParams) List(java.util.List) CredentialsType(dev.hawala.xns.level4.common.AuthChsCommon.CredentialsType) ChsDatabase(dev.hawala.xns.level4.common.ChsDatabase) PostEndResults(dev.hawala.xns.level4.mailing.MailTransport5.PostEndResults) CourierRegistry(dev.hawala.xns.level3.courier.CourierRegistry) RECORD(dev.hawala.xns.level3.courier.RECORD) ServiceErrorRecord(dev.hawala.xns.level4.mailing.MailTransport4.ServiceErrorRecord) PostBeginParams(dev.hawala.xns.level4.mailing.MailTransport5.PostBeginParams) SerializedFile(dev.hawala.xns.level4.filing.FilingCommon.SerializedFile) dev.hawala.xns.level4.filing.fs.iContentSource(dev.hawala.xns.level4.filing.fs.iContentSource) ByteArrayOutputStream(java.io.ByteArrayOutputStream) dev.hawala.xns.level3.courier.iWireStream(dev.hawala.xns.level3.courier.iWireStream) StrongVerifier(dev.hawala.xns.level4.common.AuthChsCommon.StrongVerifier) LogoffParams(dev.hawala.xns.level4.mailing.Inbasket2.LogoffParams) MiWhatever(dev.hawala.xns.level4.mailing.Inbasket2.MiWhatever) HandleMailPartsResults(dev.hawala.xns.level4.mailing.Inbasket2.HandleMailPartsResults) HashMap(java.util.HashMap) StrongAuthUtils(dev.hawala.xns.level4.common.StrongAuthUtils) AccessErrorRecord(dev.hawala.xns.level4.mailing.MailingCommon.AccessErrorRecord) ByteContentSink(dev.hawala.xns.level4.filing.ByteContentSink) STRING(dev.hawala.xns.level3.courier.STRING) ArrayList(java.util.ArrayList) WireBaseStream(dev.hawala.xns.level3.courier.WireBaseStream) Name(dev.hawala.xns.level4.common.AuthChsCommon.Name) MiMailParts(dev.hawala.xns.level4.mailing.Inbasket2.MiMailParts) WireWriter(dev.hawala.xns.level3.courier.WireWriter) GetMailPartParams(dev.hawala.xns.level4.mailing.Inbasket2.GetMailPartParams) GetNextMailParams(dev.hawala.xns.level4.mailing.Inbasket2.GetNextMailParams) MiMailServer(dev.hawala.xns.level4.mailing.Inbasket2.MiMailServer) LogonResults(dev.hawala.xns.level4.mailing.Inbasket2.LogonResults) Verifier(dev.hawala.xns.level4.common.AuthChsCommon.Verifier) PostEndParams(dev.hawala.xns.level4.mailing.MailTransport5.PostEndParams) IOException(java.io.IOException) BulkData1(dev.hawala.xns.level4.common.BulkData1) FilingCommon(dev.hawala.xns.level4.filing.FilingCommon) InbasketPollParams(dev.hawala.xns.level4.mailing.Inbasket2.InbasketPollParams) ByteContentSource(dev.hawala.xns.level4.filing.ByteContentSource) MessageID(dev.hawala.xns.level4.mailing.MailingCommon.MessageID) MiMailPart(dev.hawala.xns.level4.mailing.Inbasket2.MiMailPart) ThreePartName(dev.hawala.xns.level4.common.AuthChsCommon.ThreePartName) ThreePartNameWithTag(dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTag) State(dev.hawala.xns.level4.mailing.Inbasket1.State) MiMailPart(dev.hawala.xns.level4.mailing.Inbasket2.MiMailPart) SerializedFile(dev.hawala.xns.level4.filing.FilingCommon.SerializedFile) Attribute(dev.hawala.xns.level4.filing.FilingCommon.Attribute) ThreePartNameWithTagAndDateString(dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTagAndDateString) MiTotalPartsLength(dev.hawala.xns.level4.mailing.Inbasket2.MiTotalPartsLength) MiMailServer(dev.hawala.xns.level4.mailing.Inbasket2.MiMailServer) MiMailParts(dev.hawala.xns.level4.mailing.Inbasket2.MiMailParts) EncodedList(dev.hawala.xns.level4.mailing.MailingCommon.EncodedList) SEQUENCE(dev.hawala.xns.level3.courier.SEQUENCE) EndOfMessageException(dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException) MiSender(dev.hawala.xns.level4.mailing.Inbasket2.MiSender) ListOfThreePartNameWithTag(dev.hawala.xns.level4.mailing.MailTransport5.ListOfThreePartNameWithTag) ThreePartNameWithTag(dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTag) MessageID(dev.hawala.xns.level4.mailing.MailingCommon.MessageID) NoMoreWriteSpaceException(dev.hawala.xns.level3.courier.iWireStream.NoMoreWriteSpaceException) NameList(dev.hawala.xns.level4.mailing.MailingCommon.NameList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) MiWhatever(dev.hawala.xns.level4.mailing.Inbasket2.MiWhatever) ListOfThreePartNameWithTag(dev.hawala.xns.level4.mailing.MailTransport5.ListOfThreePartNameWithTag) WireWriter(dev.hawala.xns.level3.courier.WireWriter) STRING(dev.hawala.xns.level3.courier.STRING) ThreePartNameWithTagAndDateString(dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTagAndDateString)

Example 2 with SerializedFile

use of dev.hawala.xns.level4.filing.FilingCommon.SerializedFile in project dodo by devhawala.

the class MailingNewImpl method transport5_postMailPart.

/*
	 * postMailPart
	 *  = procedure 8
	 */
private static void transport5_postMailPart(PostMailPartParams params, RECORD results) {
    // log ingoing data
    if (logParamsAndResults) {
        StringBuilder sb = new StringBuilder();
        params.append(sb, "  ", "params");
        logf("##\n## procedure MailingNewImpl.transport5_postMailPart() -- params\n%s\n##\n", sb.toString());
    }
    // get the transaction, raising a generic courier exception as we do not know the real protocol...
    PostMailTransaction mt = getMailTransaction(params.mailTransaction.get());
    if (mt == null) {
        throw new IllegalStateException("invalid mail-transaction");
    }
    // get mail part content via bulk-data transfer
    int mailPartType = (int) (params.mailPartType.get() & 0x0000FFFFFFFF);
    String mailPartTypeName;
    switch(mailPartType) {
        case MailTransport5.mptEnvelope:
            mailPartTypeName = "mtpEnvelope";
            break;
        case MailTransport5.mptNoteGV:
            mailPartTypeName = "mtpNoteGV";
            break;
        case MailTransport5.mptNoteIA5:
            mailPartTypeName = "mtpNoteIA5";
            break;
        case MailTransport5.mptNoteISO6937:
            mailPartTypeName = "mtpNoteISO6937";
            break;
        case MailTransport5.mptAttachmentDoc:
            mailPartTypeName = "mptAttachmentDoc";
            break;
        default:
            mailPartTypeName = String.format("unknown[ %d ]", params.mailPartType.get());
    }
    logf("\n--- mail part content ( type: %s ):\n", mailPartTypeName);
    if (mailPartType == MailTransport5.mptEnvelope) {
        // load the envelope from the bulk-stream
        SEQUENCE<Attribute> envelope = new SEQUENCE<>(Attribute::make);
        loadBulkStream(envelope, params.content);
        // log the received envelope
        if (logDebug) {
            StringBuilder sb = new StringBuilder();
            envelope.append(sb, "  ", "envelope");
            logf("%s\n\n", sb.toString());
        }
        // interpret the envelope and remember relevant fields in our mail-transaction
        try {
            for (int i = 0; i < envelope.size(); i++) {
                Attribute attr = envelope.get(i);
                int attrType = (int) (attr.type.get() & 0xFFFF_FFFFL);
                switch(attrType) {
                    case MailTransport5.atSenderAndDate:
                        {
                            ThreePartNameWithTag attrValue = attr.decodeData(ThreePartNameWithTag::make);
                            if (attrValue.tag.get() != 0) {
                                throw new IllegalStateException("atSenderAndDate-Tag not zero");
                            }
                            mt.senderName = attrValue.name;
                        }
                        break;
                    case MailTransport5.atTo:
                        {
                            mt.toNames = attr.decodeData(ListOfThreePartNameWithTag::make);
                            for (int idx = 0; idx < mt.toNames.size(); idx++) {
                                mt.recipients.add(mt.toNames.get(idx).name);
                            }
                        }
                        break;
                    case MailTransport5.atCopiesTo:
                        {
                            mt.ccNames = attr.decodeData(ListOfThreePartNameWithTag::make);
                            for (int idx = 0; idx < mt.ccNames.size(); idx++) {
                                mt.recipients.add(mt.ccNames.get(idx).name);
                            }
                        }
                        break;
                    case MailTransport5.atReplyTo:
                        {
                            mt.replyToNames = attr.decodeData(ListOfThreePartNameWithTag::make);
                        }
                        break;
                    case MailTransport5.atSubject:
                        {
                            mt.subject = attr.decodeData(STRING::make);
                        }
                        break;
                }
            }
        } catch (EndOfMessageException e) {
            e.printStackTrace();
            throw new IllegalStateException(e);
        }
    } else if (mailPartType == MailTransport5.mptAttachmentDoc) {
        // get the serialized document(-tree) from the bulk-stream
        SerializedFile attachment = SerializedFile.make();
        loadBulkStream(attachment, params.content);
        // log the document-(tree)
        if (logDebug) {
            StringBuilder sb = new StringBuilder();
            attachment.append(sb, "  ", "attached document");
            logf("%s\n\n", sb.toString());
        }
        // save the document(-tree) in our mail-transaction
        mt.attachment = attachment;
    } else {
        try {
            // get the uninterpreted bulk-stream
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ByteContentSource source = new ByteContentSource(params.content);
            byte[] buffer = new byte[512];
            int count = source.read(buffer);
            while (count > 0) {
                bos.write(buffer, 0, count);
                count = source.read(buffer);
            }
            byte[] mailPartContent = bos.toByteArray();
            // log the received content
            if (logDebug) {
                int byteLength = mailPartContent.length;
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < byteLength; i++) {
                    int b = mailPartContent[i] & 0x00FF;
                    if ((i % 16) == 0) {
                        logf("%s\n              0x%03X :", sb.toString(), i);
                        sb.setLength(0);
                        sb.append("  ");
                    }
                    logf(" %02X", b);
                    if (b >= 32 && b < 127) {
                        sb.append((char) b);
                    } else {
                        sb.append("∙");
                    }
                }
                int gap = byteLength % 16;
                String filler = (gap == 0) ? "" : blanks.substring(0, (16 - gap) * 3);
                logf("%s%s\n\n", filler, sb.toString());
            }
            // and now try to decode the mail part
            iWireStream iws = null;
            switch(mailPartType) {
                case MailTransport5.mptNoteGV:
                case MailTransport5.mptNoteIA5:
                    iws = new ByteArrayWireInputStream(mailPartContent.length, mailPartContent);
                    break;
                case MailTransport5.mptNoteISO6937:
                    // not really supported so far: any non-ascii chars are ignored (dropped)
                    int len = 0;
                    for (int i = 0; i < mailPartContent.length; i++) {
                        byte b = mailPartContent[i];
                        if (b >= 0) {
                            mailPartContent[len++] = b;
                        }
                    }
                    iws = new ByteArrayWireInputStream(len, mailPartContent);
                    break;
            }
            if (iws != null) {
                STRING s = STRING.make();
                s.deserialize(iws);
                mt.mailText = s;
            }
        } catch (EndOfMessageException e) {
            e.printStackTrace();
            throw new IllegalStateException(e);
        }
    }
    // log outgoing data
    if (logParamsAndResults) {
        StringBuilder sb = new StringBuilder();
        results.append(sb, "  ", "results");
        logf("##\n## procedure MailingNewImpl.transport5_postMailPart() -- results\n%s\n##\n", sb.toString());
    }
}
Also used : Attribute(dev.hawala.xns.level4.filing.FilingCommon.Attribute) SerializedFile(dev.hawala.xns.level4.filing.FilingCommon.SerializedFile) dev.hawala.xns.level3.courier.iWireStream(dev.hawala.xns.level3.courier.iWireStream) ThreePartNameWithTagAndDateString(dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTagAndDateString) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ListOfThreePartNameWithTag(dev.hawala.xns.level4.mailing.MailTransport5.ListOfThreePartNameWithTag) SEQUENCE(dev.hawala.xns.level3.courier.SEQUENCE) STRING(dev.hawala.xns.level3.courier.STRING) EndOfMessageException(dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException) ByteContentSource(dev.hawala.xns.level4.filing.ByteContentSource) ListOfThreePartNameWithTag(dev.hawala.xns.level4.mailing.MailTransport5.ListOfThreePartNameWithTag) ThreePartNameWithTag(dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTag)

Example 3 with SerializedFile

use of dev.hawala.xns.level4.filing.FilingCommon.SerializedFile in project dodo by devhawala.

the class FilingImpl method serialize.

/*
	 * Serialize: PROCEDURE [ file: Handle, serializedFile: BulkData.Sink,
	 *                        session: Session ]
	 *   REPORTS [ AccessError, AuthenticationError, ConnectionError,
	 *             HandleError, SessionError, TransferError, UndefinedError ]
	 *   = 15;
	 */
private static void serialize(SerializeParams params, RECORD results) {
    logParams("serialize", params);
    // check session
    Session session = resolveSession(params.session);
    // check file
    Handle fileHandle = Handle.get(params.file);
    if (fileHandle == null || fileHandle.isNullHandle()) {
        new HandleErrorRecord(HandleProblem.nullDisallowed).raise();
    }
    if (fileHandle.isVolumeRoot()) {
        new AccessErrorRecord(AccessProblem.accessRightsInsufficient).raise();
    }
    // prevent session timeout when processing large trees
    session.holdClosing();
    try {
        // build up the tree structure
        SerializedFile serializedFile = new SerializedFile(ws -> new SerializeTreeWireStream(ws, session), session.getFilingVersion() < 5);
        FileEntry startFe = fileHandle.getFe();
        fillSerializeData(startFe, serializedFile.file, session.getFilingVersion());
        // transfer the data
        sendBulkData("serialize", params.serializedFile, serializedFile);
    } finally {
        // restart timeout checks on the session
        session.continueUse();
    }
}
Also used : AccessErrorRecord(dev.hawala.xns.level4.filing.FilingCommon.AccessErrorRecord) SerializedFile(dev.hawala.xns.level4.filing.FilingCommon.SerializedFile) HandleErrorRecord(dev.hawala.xns.level4.filing.FilingCommon.HandleErrorRecord) FileEntry(dev.hawala.xns.level4.filing.fs.FileEntry)

Example 4 with SerializedFile

use of dev.hawala.xns.level4.filing.FilingCommon.SerializedFile in project dodo by devhawala.

the class FilingImpl method deserialize.

/*
	 * Deserialize: PROCEDURE [ directory: Handle, attributes: AttributeSequence,
	 *                          controls: ControlSequence, serializedFile: BulkData.Source,
	 *                          session: Session ]
	 *   RETURNS [ file: Handle ]
	 *   REPORTS [ AccessError, AttributeTypeError, AttributeValueError,
	 *             AuthenticationError, ConnectionError, ControlTypeError,
	 *             ControlValueError, HandleError, InsertionError,
	 *             SessionError, SpaceError, TransferError, UndefinedError ]
	 *   = 16;
	 */
private static void deserialize(DeserializeParams params, FileHandleRecord results) {
    logParams("deserialize", params);
    // check session
    Session session = resolveSession(params.session);
    // check directory
    Handle dirHandle = Handle.get(params.directory);
    if (dirHandle == null || dirHandle.isNullHandle()) {
        new HandleErrorRecord(HandleProblem.nullDisallowed).raise();
    }
    if (dirHandle.isVolumeRoot()) {
        new AccessErrorRecord(AccessProblem.accessRightsInsufficient).raise();
    }
    // prevent session timeout when processing large trees
    session.holdClosing();
    // do the transfer and deserialization
    try (Volume.Session modSession = session.getService().getVolume().startModificationSession()) {
        SerializedFile deserializedFile = new SerializedFile(ws -> new DeserializeTreeWireStream(ws, dirHandle.getFe().getFileID(), session, results, modSession), false);
        params.serializedFile.receive(deserializedFile);
    } catch (EndOfMessageException e) {
        new ConnectionErrorRecord(ConnectionProblem.otherCallProblem).raise();
    } catch (Exception e) {
        System.out.printf("!!! Exception: %s -- %s !!!\n", e.getClass().getName(), e.getMessage());
        new SpaceErrorRecord(SpaceProblem.mediumFull).raise();
    } finally {
        // restart timeout checks on the session
        session.continueUse();
    }
}
Also used : AccessErrorRecord(dev.hawala.xns.level4.filing.FilingCommon.AccessErrorRecord) Volume(dev.hawala.xns.level4.filing.fs.Volume) SerializedFile(dev.hawala.xns.level4.filing.FilingCommon.SerializedFile) HandleErrorRecord(dev.hawala.xns.level4.filing.FilingCommon.HandleErrorRecord) EndOfMessageException(dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException) SpaceErrorRecord(dev.hawala.xns.level4.filing.FilingCommon.SpaceErrorRecord) ConnectionErrorRecord(dev.hawala.xns.level4.filing.FilingCommon.ConnectionErrorRecord) NoMoreWriteSpaceException(dev.hawala.xns.level3.courier.iWireStream.NoMoreWriteSpaceException) EndOfMessageException(dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException) IOException(java.io.IOException) CourierException(dev.hawala.xns.level3.courier.exception.CourierException)

Example 5 with SerializedFile

use of dev.hawala.xns.level4.filing.FilingCommon.SerializedFile in project dodo by devhawala.

the class MailingNewImpl method transport5_postEnd.

/*
	 * postEnd
	 *  = procedure 9
	 */
private static void transport5_postEnd(PostEndParams params, PostEndResults results) {
    // log ingoing data
    if (logParamsAndResults) {
        StringBuilder sb = new StringBuilder();
        params.append(sb, "  ", "params");
        logf("##\n## procedure MailingNewImpl.transport5_postEnd() -- params\n%s\n##\n", sb.toString());
    }
    // get the transaction, raising a generic courier exception as we do not know the real protocol...
    PostMailTransaction mt = getMailTransaction(params.mailTransaction.get());
    if (mt == null) {
        throw new IllegalStateException("invalid mail-transaction");
    }
    // collect recipients
    NameList allRecipients = NameList.make();
    ChsDatabase chs = mailService.getChsDatabase();
    for (ThreePartName rcpt : mt.recipients) {
        String rcptFqn = chs.resolveName(rcpt);
        List<Name> dlMemberNames;
        if (rcptFqn != null && mailService.hasMailbox(rcptFqn)) {
            Name rcptName = Name.make();
            rcptName.from(rcptFqn);
            allRecipients.addDistinct(rcptName);
        } else if (rcptFqn != null && (dlMemberNames = MailingOldImpl.getUserGroupMembersLcFqns(rcptFqn)) != null) {
            for (Name dlMember : dlMemberNames) {
                allRecipients.addDistinct(dlMember);
            }
        }
    }
    if (allRecipients.size() == 0) {
        if (logParamsAndResults) {
            StringBuilder sb = new StringBuilder();
            results.append(sb, "  ", "results");
            logf("##\n## procedure MailingNewImpl.transport5_postEnd() -- results (NO valid RECIPIENTS)\n%s\n##\n", sb.toString());
        }
        // leave messageId as all-zeroes => (hopefully) NullID => (hopefully) message not sent
        return;
    }
    // create the items for the mail service
    SerializedFile mailContentFile = mt.attachment;
    if (mailContentFile == null) {
        // no attached serialized item => produce one with the attributes used by Star..VP2.x
        // force version = 2
        mailContentFile = new SerializedFile(null, true);
        // leave the content  proper empty
        mailContentFile.file.content.lastByteSignificant.set(true);
        SEQUENCE<Attribute> attrs = mailContentFile.file.attributes.value;
        attrs.add().set(FilingCommon.atAccessList, FilingCommon.AccessList::make4, v -> v.defaulted.set(true));
        attrs.add().setAsTime(FilingCommon.atBackedUpOn, mt.mailPostTime.get());
        attrs.add().setAsCardinal(FilingCommon.atChecksum, 0xFFFF);
        attrs.add().setAsChsName(FilingCommon.atCreatedBy, mt.senderName);
        attrs.add().setAsTime(FilingCommon.atCreatedOn, mt.mailPostTime.get());
        attrs.add().setAsBoolean(FilingCommon.atIsDirectory, false);
        attrs.add().set(MailingCommon.subject, STRING::make, v -> v.set(mt.subject));
        attrs.add().setAsLongCardinal(MailingCommon.bodySize, 0);
        attrs.add().setAsLongCardinal(FilingCommon.atStoredSize, 0);
        attrs.add().setAsLongCardinal(FilingCommon.atSubtreeSize, 0);
        attrs.add().setAsLongCardinal(MailingCommon.bodyType, FilingCommon.tVPMailNote);
        attrs.add().setAsCardinal(4402, 0);
        attrs.add().setAsCardinal(4401, 1);
        attrs.add().setAsCardinal(4348, 11);
        attrs.add().setAsCardinal(4403, 0x005C009E);
        attrs.add().setAsBoolean(MailingCommon.coversheetOn, true);
        attrs.add().set(MailingCommon.from, NameList::make, v -> v.add().from(mt.senderName));
        attrs.add().set(MailingCommon.to, NameList::make, v -> copyNames(mt.toNames, v));
        attrs.add().set(MailingCommon.comments, STRING::make, v -> v.set(mt.mailText));
        attrs.add().set(MailingCommon.cc, NameList::make, v -> copyNames(mt.ccNames, v));
    } else {
        // check if all required Star..VP2.x attributes are present, adding the missing ones if necessary
        boolean hasMailFrom = false;
        boolean hasMailTo = false;
        boolean hasMailCc = false;
        boolean hasCoversheetOn = false;
        SEQUENCE<Attribute> attrs = mailContentFile.file.attributes.value;
        for (int i = 0; i < attrs.size(); i++) {
            int attributeType = (int) (attrs.get(i).type.get() & 0xFFFF_FFFFL);
            hasMailFrom |= (attributeType == MailingCommon.from);
            hasMailTo |= (attributeType == MailingCommon.to);
            hasMailCc |= (attributeType == MailingCommon.cc);
            hasCoversheetOn |= (attributeType == MailingCommon.coversheetOn);
        }
        if (!hasCoversheetOn) {
            attrs.add().setAsBoolean(MailingCommon.coversheetOn, true);
        }
        if (!hasMailFrom) {
            attrs.add().set(MailingCommon.from, NameList::make, v -> v.add().from(mt.senderName));
        }
        if (!hasMailTo) {
            attrs.add().set(MailingCommon.to, NameList::make, v -> copyNames(mt.toNames, v));
        }
        if (!hasMailCc) {
            attrs.add().set(MailingCommon.cc, NameList::make, v -> copyNames(mt.ccNames, v));
        }
    }
    // create the mail
    iContentSource source = new MailService.ValueContentSource(mailContentFile);
    int[] mailId = mailService.postMail(mt.senderName, allRecipients, MailingCommon.ctSerializedFile, source);
    // set return values
    for (int i = 0; i < mailId.length; i++) {
        results.messageId.get(i).set(mailId[i]);
    }
    // we're done with this mail, so forget the mail transaction
    dropMailTransaction(mt);
    // log outgoing data
    if (logParamsAndResults) {
        StringBuilder sb = new StringBuilder();
        results.append(sb, "  ", "results");
        logf("##\n## procedure MailingNewImpl.transport5_postEnd() -- results\n%s\n##\n", sb.toString());
    }
}
Also used : NameList(dev.hawala.xns.level4.mailing.MailingCommon.NameList) SerializedFile(dev.hawala.xns.level4.filing.FilingCommon.SerializedFile) Attribute(dev.hawala.xns.level4.filing.FilingCommon.Attribute) ThreePartNameWithTagAndDateString(dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTagAndDateString) Name(dev.hawala.xns.level4.common.AuthChsCommon.Name) ThreePartName(dev.hawala.xns.level4.common.AuthChsCommon.ThreePartName) dev.hawala.xns.level4.filing.fs.iContentSource(dev.hawala.xns.level4.filing.fs.iContentSource) ThreePartName(dev.hawala.xns.level4.common.AuthChsCommon.ThreePartName) STRING(dev.hawala.xns.level3.courier.STRING) ChsDatabase(dev.hawala.xns.level4.common.ChsDatabase)

Aggregations

SerializedFile (dev.hawala.xns.level4.filing.FilingCommon.SerializedFile)5 STRING (dev.hawala.xns.level3.courier.STRING)3 EndOfMessageException (dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException)3 Attribute (dev.hawala.xns.level4.filing.FilingCommon.Attribute)3 ThreePartNameWithTagAndDateString (dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTagAndDateString)3 SEQUENCE (dev.hawala.xns.level3.courier.SEQUENCE)2 dev.hawala.xns.level3.courier.iWireStream (dev.hawala.xns.level3.courier.iWireStream)2 NoMoreWriteSpaceException (dev.hawala.xns.level3.courier.iWireStream.NoMoreWriteSpaceException)2 Name (dev.hawala.xns.level4.common.AuthChsCommon.Name)2 ThreePartName (dev.hawala.xns.level4.common.AuthChsCommon.ThreePartName)2 ChsDatabase (dev.hawala.xns.level4.common.ChsDatabase)2 ByteContentSource (dev.hawala.xns.level4.filing.ByteContentSource)2 AccessErrorRecord (dev.hawala.xns.level4.filing.FilingCommon.AccessErrorRecord)2 HandleErrorRecord (dev.hawala.xns.level4.filing.FilingCommon.HandleErrorRecord)2 dev.hawala.xns.level4.filing.fs.iContentSource (dev.hawala.xns.level4.filing.fs.iContentSource)2 ListOfThreePartNameWithTag (dev.hawala.xns.level4.mailing.MailTransport5.ListOfThreePartNameWithTag)2 ThreePartNameWithTag (dev.hawala.xns.level4.mailing.MailTransport5.ThreePartNameWithTag)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 CourierRegistry (dev.hawala.xns.level3.courier.CourierRegistry)1