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);
}
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());
}
}
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();
}
}
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();
}
}
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());
}
}
Aggregations