diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/NotesDatabase.java b/domino-jna/src/main/java/com/mindoo/domino/jna/NotesDatabase.java index 45b4a85e..62b9b082 100755 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/NotesDatabase.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/NotesDatabase.java @@ -4056,6 +4056,10 @@ private int toNoteOpenOptions(Set flags) { options = options | NotesConstants.OPEN_WITH_FOLDERS; } + if (flags.contains(OpenNote.CACHE)) { + options = options | NotesConstants.OPEN_CACHE; + } + // we negated the following two OPEN_XXX constants, so we keep // the items in their native format if conversion is not explicitly requested diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/NotesNote.java b/domino-jna/src/main/java/com/mindoo/domino/jna/NotesNote.java index aad6b294..8da9b79e 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/NotesNote.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/NotesNote.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.EnumSet; @@ -58,6 +59,7 @@ import com.mindoo.domino.jna.internal.Mem64; import com.mindoo.domino.jna.internal.NotesCallbacks; import com.mindoo.domino.jna.internal.NotesConstants; +import com.mindoo.domino.jna.internal.NotesNativeAPI; import com.mindoo.domino.jna.internal.NotesNativeAPI32; import com.mindoo.domino.jna.internal.NotesNativeAPI64; import com.mindoo.domino.jna.internal.ReadOnlyMemory; @@ -87,9 +89,12 @@ import com.mindoo.domino.jna.richtext.RichTextBuilder; import com.mindoo.domino.jna.richtext.StandaloneRichText; import com.mindoo.domino.jna.richtext.conversion.IRichTextConversion; +import com.mindoo.domino.jna.utils.IDUtils; import com.mindoo.domino.jna.utils.LegacyAPIUtils; +import com.mindoo.domino.jna.utils.ListUtil; import com.mindoo.domino.jna.utils.Loop; import com.mindoo.domino.jna.utils.NotesDateTimeUtils; +import com.mindoo.domino.jna.utils.NotesNamingUtils; import com.mindoo.domino.jna.utils.NotesStringUtils; import com.mindoo.domino.jna.utils.PlatformUtils; import com.mindoo.domino.jna.utils.Ref; @@ -102,6 +107,7 @@ import com.sun.jna.ptr.DoubleByReference; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; +import com.sun.jna.ptr.PointerByReference; import com.sun.jna.ptr.ShortByReference; import lotus.domino.Database; @@ -1286,6 +1292,7 @@ public void removeItem(String itemName) { private final int MAX_STRINGRETVALUE_LENGTH = 65535; private ThreadLocal stringretBuffer = new ThreadLocal(); + private boolean m_saveMessageOnSend; /** * Use this function to read the value of a text item.
@@ -6694,4 +6701,718 @@ public String getPrimaryKeyObjectId() { return ""; } + + private NotesNote cloneNote() { + checkHandle(); + + short result; + if (PlatformUtils.is64Bit()) { + LongByReference rethDstNote = new LongByReference(); + result = NotesNativeAPI64.get().NSFNoteCreateClone(m_hNote64, rethDstNote); + NotesErrorUtils.checkResult(result); + + NotesNote clone = new NotesNote(m_parentDb, rethDstNote.getValue()); + NotesGC.__objectCreated(NotesNote.class, clone); + return clone; + } + else { + IntByReference rethDstNote = new IntByReference(); + result = NotesNativeAPI32.get().NSFNoteCreateClone(m_hNote32, rethDstNote); + NotesErrorUtils.checkResult(result); + + NotesNote clone = new NotesNote(m_parentDb, rethDstNote.getValue()); + NotesGC.__objectCreated(NotesNote.class, clone); + return clone; + } + } + + /** + * Mails the note
+ * Convenience function that calls {@link #send(boolean, Collection)}. + */ + public void send() { + send(false, (Collection) null); + } + + /** + * Mails the note
+ * Convenience function that calls {@link #send(boolean, Collection)}. + * + * @param recipients The recipients of the document, may include people, groups, or mail-in databases. + */ + public void send(String recipient) { + send(false, Arrays.asList(recipient)); + } + + /** + * Mails the note
+ * Convenience function that calls {@link #send(boolean, Collection)}. + * + * @param recipients The recipients of the document, may include people, groups, or mail-in databases. + */ + public void send(Collection recipients) { + send(false, recipients); + } + + /** + * Mails the note
+ * Convenience function that calls {@link #send(boolean, Collection)}. + * + * @param attachform If true, the form is stored and sent along with the document. If false, it isn't. Do not attach a form that uses computed subforms. + */ + public void send(boolean attachform) { + send(attachform, (Collection) null); + } + + /** + * Mails the note
+ * Convenience function that calls {@link #send(boolean, Collection)}. + * + * @param attachform If true, the form is stored and sent along with the document. If false, it isn't. Do not attach a form that uses computed subforms. + * @param recipient The recipient of the document, may include people, groups, or mail-in databases. + */ + public void send(boolean attachform, String recipient) { + send(attachform, Arrays.asList(recipient)); + } + + /** + * Indicates whether a document is saved to a database when mailed. + * + * @return true to save on send + */ + public boolean isSaveMessageOnSend() { + return m_saveMessageOnSend; + } + + /** + * Indicates whether a document is saved to a database when mailed. + * + * @param b true to save on send + */ + public void setSaveMessageOnSend(boolean b) { + m_saveMessageOnSend = b; + } + + /** + * Mails the note
+ *
+ * Two kinds of items can affect the mailing of the document when you use send:
+ *
    + *
  • If the document contains additional recipient items, such as CopyTo or BlindCopyTo, the documents mailed to those recipients.
  • + *
  • If the document contains items to control the routing of mail, such as DeliveryPriority, DeliveryReport, or ReturnReceipt, they are used when sending the document.
  • + *
+ * The {@link #isSaveMessageOnSend()} property controls whether the sent document is saved + * in the database. If {@link #isSaveMessageOnSend()} is true and you attach the form to the document, + * the form is saved with the document.
+ * Sending the form increases the size of the document, but ensures that the recipient can see + * all of the items on the document. + * + * @param attachform If true, the form is stored and sent along with the document. If false, it isn't. Do not attach a form that uses computed subforms. + * @param recipients The recipients of the document, may include people, groups, or mail-in databases. + */ + public void send(boolean attachform, Collection recipients) { + checkHandle(); + + if (m_parentDb.isRecycled()) { + throw new NotesError("Parent database is recycled"); + } + + short flags = 0; + + if (this.isSigned() || attachform) { + flags |= NotesConstants.MSN_SIGN; + } + + if (this.isSealed()) { + flags |= NotesConstants.MSN_SEAL; + } + + boolean cancelsend = false; + if (cancelsend) { + flags |= NotesConstants.MSN_PUBKEY_ONLY; + } + + Ref foundNonBodyMIME = new Ref<>(); + Ref foundBodyMIME = new Ref<>(); + this.searchForNonBodyMIME(foundNonBodyMIME, foundBodyMIME); + + if (Boolean.TRUE.equals(foundNonBodyMIME.get())) { + throw new NotesError("Found items of type MIME_PART that are not named 'Body'. This is currently unsupported."); + } + + short wMailNoteFlags = NotesConstants.MAILNOTE_ANYRECIPIENT; + + if (Boolean.TRUE.equals(foundBodyMIME.get())) { + wMailNoteFlags |= NotesConstants.MAILNOTE_MIMEBODY; + wMailNoteFlags |= NotesConstants.MAILNOTE_NOTES_ENCRYPT_MIME; + } + + /* SPR ajrs39vm4l: We're about to modify the user's note. + * If they do something stupid, like send it a second time, + * we're going to modify it again, ending up with all sorts + * of duplicate items that will cause problems for the recipient. + * So, we fix that by cloning the hnote here, making all + * modifications on the copy. + * + * Note that we use NULL for the hdb when creating the note + * to prevent a network round trip. Then we have to set the + * hdb explicitly into the note. Later, after sending the thing, + * we have to check to see if the original hnote needs updating + * (for example, if the current note is not on disk, but the + * user specified "save on send", then we have to update the + * note id). + */ + + //create a clone to not modify this note instance and prevent issues when sending a second time + NotesNote tmpNote = cloneNote(); + + // now copy all items to the new note + if (PlatformUtils.is64Bit()) { + short copyItemsResult = NotesNativeAPI64.get().NSFNoteReplaceItems(getHandle64(), tmpNote.getHandle64(), + null, true); + NotesErrorUtils.checkResult(copyItemsResult); + } + else { + short copyItemsResult = NotesNativeAPI32.get().NSFNoteReplaceItems(getHandle32(), tmpNote.getHandle32(), + null, true); + NotesErrorUtils.checkResult(copyItemsResult); + } + + // did caller provide a recipients list? + if (recipients!=null) { + // if there's already a SendTo item, delete it + NotesItem sendto = tmpNote.getFirstItem(NotesConstants.MAIL_SENDTO_ITEM); + if (sendto!=null) { + sendto.remove(); + } + + recipients = NotesNamingUtils.toCanonicalNames(recipients); + tmpNote.replaceItemValue(NotesConstants.MAIL_SENDTO_ITEM, recipients); + } + + if (tmpNote.hasItem(NotesConstants.MAIL_COPYTO_ITEM)) { + List copyToNames = tmpNote.getItemValueStringList(NotesConstants.MAIL_COPYTO_ITEM); + copyToNames = NotesNamingUtils.toCanonicalNames(copyToNames); + tmpNote.replaceItemValue(NotesConstants.MAIL_COPYTO_ITEM, copyToNames); + } + + if (tmpNote.hasItem(NotesConstants.MAIL_BLINDCOPYTO_ITEM)) { + List blindCopyToNames = tmpNote.getItemValueStringList(NotesConstants.MAIL_COPYTO_ITEM); + blindCopyToNames = NotesNamingUtils.toCanonicalNames(blindCopyToNames); + tmpNote.replaceItemValue(NotesConstants.MAIL_BLINDCOPYTO_ITEM, blindCopyToNames); + } + + if (!tmpNote.hasItem(NotesConstants.MAIL_SENDTO_ITEM) && !tmpNote.hasItem(NotesConstants.MAIL_COPYTO_ITEM) && + !tmpNote.hasItem(NotesConstants.MAIL_BLINDCOPYTO_ITEM)) { + throw new NotesError(0, "Missing mail recipient items"); + } + + /* To attach the form, find it in the database, get the all + * items from the form note beginning with '$' (with some + * exceptions), and copy them to the mail note. Then, + * we have to delete the Form item, which points to the original + * form name. By deleting it, we're telling the editor to look + * for the stored form instead. + * + * If the form contains a SUBFORM_ITEM (textlist of the + * names of subforms used in the form), then we have + * to copy a bunch of sub-form stuff too + */ + + if (attachform) { + // Remove old stored form items before adding items from another form + short removeStoredFormResult; + if (PlatformUtils.is64Bit()) { + removeStoredFormResult = NotesNativeAPI64.get().StoredFormRemoveItems(tmpNote.getHandle64(), 0); + } + else { + removeStoredFormResult = NotesNativeAPI32.get().StoredFormRemoveItems(tmpNote.getHandle32(), 0); + } + NotesErrorUtils.checkResult(removeStoredFormResult); + + NotesItem formname = tmpNote.getFirstItem(NotesConstants.FIELD_FORM); + NotesItem body = tmpNote.getFirstItem(NotesConstants.ITEM_NAME_TEMPLATE); + + IntByReference fnid = new IntByReference(); + fnid.setValue(0); + + if (formname!=null) { + String formnameStr = tmpNote.getItemValueString(NotesConstants.FIELD_FORM); + /* Delete the form item from the note, we copied the name. + * We don't want a Form item on the note when we attach + * the form itself, otherwise the editor gets confused. + * Doing the Remove also deletes the object. */ + formname.remove(); + + if (!StringUtil.isEmpty(formnameStr)) { + Memory formnameStrMem = NotesStringUtils.toLMBCS(formnameStr, true); + PointerByReference pName = new PointerByReference(); + ShortByReference wNameLen = new ShortByReference(); + PointerByReference pAlias = new PointerByReference(); + ShortByReference wAliasLen = new ShortByReference(); + + NotesNativeAPI.get().DesignGetNameAndAlias(formnameStrMem, pName, wNameLen, pAlias, wAliasLen); + + DisposableMemory szBuffer = new DisposableMemory(NotesConstants.DESIGN_ALL_NAMES_MAX); + szBuffer.clear(); + + if (wAliasLen.getValue()>0) { + byte[] aliasArr = pAlias.getValue().getByteArray(0, (int) (wAliasLen.getValue() & 0xffff)); + szBuffer.write(0, aliasArr, 0, aliasArr.length); + } + else { + byte[] wNameArr = pName.getValue().getByteArray(0, (int) (wNameLen.getValue() & 0xffff)); + szBuffer.write(0, wNameArr, 0, wNameArr.length); + } + + short lkFormResult; + Memory szFlagsPatternMem = NotesStringUtils.toLMBCS(NotesConstants.DFLAGPAT_VIEWFORM_ALL_VERSIONS, true); + + if (PlatformUtils.is64Bit()) { + lkFormResult = NotesNativeAPI64.get().DesignLookupNameFE(m_parentDb.getHandle64(), + NotesConstants.NOTE_CLASS_FORM, szFlagsPatternMem, + szBuffer, wAliasLen.getValue()>0 ? wAliasLen.getValue() : wNameLen.getValue(), + NotesConstants.DGN_ONLYSHARED, fnid, (IntByReference) null, + (NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC) null, null); + } + else { + lkFormResult = NotesNativeAPI32.get().DesignLookupNameFE(m_parentDb.getHandle32(), + NotesConstants.NOTE_CLASS_FORM, szFlagsPatternMem, + szBuffer, wAliasLen.getValue()>0 ? wAliasLen.getValue() : wNameLen.getValue(), + NotesConstants.DGN_ONLYSHARED, fnid, (IntByReference) null, + (NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC) null, null); + + } + + if (lkFormResult!=0) { + /* Try private. */ + if (PlatformUtils.is64Bit()) { + lkFormResult = NotesNativeAPI64.get().DesignLookupNameFE(m_parentDb.getHandle64(), + NotesConstants.NOTE_CLASS_FORM, szFlagsPatternMem, + szBuffer, wAliasLen.getValue()>0 ? wAliasLen.getValue() : wNameLen.getValue(), + NotesConstants.DGN_ONLYPRIVATE, fnid, (IntByReference) null, + (NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC) null, null); + } + else { + lkFormResult = NotesNativeAPI32.get().DesignLookupNameFE(m_parentDb.getHandle32(), + NotesConstants.NOTE_CLASS_FORM, szFlagsPatternMem, + szBuffer, wAliasLen.getValue()>0 ? wAliasLen.getValue() : wNameLen.getValue(), + NotesConstants.DGN_ONLYPRIVATE, fnid, (IntByReference) null, + (NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC) null, null); + } + } + + if (lkFormResult==0) { + // delete existing $body + while (tmpNote.hasItem(NotesConstants.ITEM_NAME_TEMPLATE)) { + tmpNote.removeItem(NotesConstants.ITEM_NAME_TEMPLATE); + } + + NotesNote formNote = getParent().openNoteById(fnid.getValue(), EnumSet.of(OpenNote.CACHE)); + if (formNote!=null) { + List excludeList = Arrays.asList( + NotesConstants.DESIGN_CLASS, + NotesConstants.DESIGN_FLAGS, + NotesConstants.FIELD_UPDATED_BY); + + // do the $ items + copyFormItems(formNote, tmpNote, excludeList); + + // check for subforms + copySubformItems(formNote, tmpNote); + + // this will add the new, more secure style of stored form and subform items + // to the target doc + // Note: This has to be done after $Body item(s) have been added to the note + // by copyFormItems + + short addStoredFormResult; + if (PlatformUtils.is64Bit()) { + addStoredFormResult = NotesNativeAPI64.get().StoredFormAddItems(m_parentDb.getHandle64(), + formNote.getHandle64(), + tmpNote.getHandle64(), true, 0); + } + else { + addStoredFormResult = NotesNativeAPI32.get().StoredFormAddItems(m_parentDb.getHandle32(), + formNote.getHandle32(), + tmpNote.getHandle32(), true, 0); + + } + NotesErrorUtils.checkResult(addStoredFormResult); + + formNote.recycle(); + } + } + } + } + else { + /* If have body and blank form, use existing body */ + if (body==null) { + throw new NotesError("No form found to attach"); + } + } + } + + final boolean isMsgComingFromAgent = false; + if (isMsgComingFromAgent) { + if (!tmpNote.hasItem(NotesConstants.ASSIST_MAIL_ITEM)) { + tmpNote.replaceItemValue(NotesConstants.ASSIST_MAIL_ITEM, "1"); + } + } + + /* IETF standard auto flag */ + tmpNote.replaceItemValue(NotesConstants.MAIL_ITEM_AUTOSUBMITTED, NotesConstants.MAIL_AUTOGENERATED); + + /* If this is happening on a server, then we want to tag the + * message as being from the effective user, not from the server. + * Always check for the special "from" item, though, in case the + * user is getting tricky with us */ + + // if there's already a From item, delete it + NotesItem from = tmpNote.getFirstItem(NotesConstants.MAIL_FROM_ITEM); + if (from!=null) { + from.remove(); + } + + if (IDUtils.isOnServer() || Boolean.TRUE.equals(NotesGC.getCustomValue("notesnote.sendasotheruser"))) { // we added a flag here to test this in the client + String effUserName = IDUtils.getEffectiveUsername(); + if (!StringUtil.isEmpty(effUserName)) { + effUserName = NotesNamingUtils.toCanonicalName(effUserName); + + tmpNote.replaceItemValue(NotesConstants.MAIL_FROM_ITEM, effUserName); + } + } + + // Contract before sending to be editor-compatible + short contractResult; + if (PlatformUtils.is64Bit()) { + contractResult = NotesNativeAPI64.get().NSFNoteContract(m_hNote64); + } + else { + contractResult = NotesNativeAPI32.get().NSFNoteContract(m_hNote32); + } + NotesErrorUtils.checkResult(contractResult); + + /*spr bban3kzhk9 -- allow sendto AND/OR copyto AND/OR blindcopyto */ + /* snis6z2taf et al. -- reinstate ability to MIME encrypt, + by flagging any MIME body for the mailer */ + short mailNoteResult; + if (PlatformUtils.is64Bit()) { + mailNoteResult = NotesNativeAPI64.get().MailNoteJitEx2(null, tmpNote.getHandle64(), flags, null, + NotesConstants.MAIL_NO_JIT, wMailNoteFlags, null, null); + } + else { + mailNoteResult = NotesNativeAPI32.get().MailNoteJitEx2(null, tmpNote.getHandle32(), flags, null, + NotesConstants.MAIL_NO_JIT, wMailNoteFlags, null, null); + } + NotesErrorUtils.checkResult(mailNoteResult); + + /* must replace certain critical item(s) on original note with their new after + * mailing values so that the note will appear in 'Sent' view, etc. + * Note: wholesale replacement of all items with new values will result in a + * regression problem with spr ajrs39vm4l + */ + + /* here we query the new copy for posted date */ + NotesTimeDate postedDate = tmpNote.getItemValueAsTimeDate(NotesConstants.MAIL_POSTEDDATE_ITEM); + + removeItem(NotesConstants.MAIL_POSTEDDATE_ITEM); + if (postedDate!=null) { + replaceItemValue(NotesConstants.MAIL_POSTEDDATE_ITEM, postedDate); + } + + // save the msg? + if (isSaveMessageOnSend()) { + // Message recall does not work for mails sent from a DIIOP program + // need to generate message id for the recall feature to work. + // Make sure deleting the existing message id if it is present and re-create new one to match with + // the one in local mail.box for the recall feature to work. + + if (hasItem(NotesConstants.MAIL_ID_ITEM)) { + removeItem(NotesConstants.MAIL_ID_ITEM); + } + + DisposableMemory messageId = new DisposableMemory(NotesConstants.MAXPATH+1); + short setMsgIdResult; + if (PlatformUtils.is64Bit()) { + setMsgIdResult = NotesNativeAPI64.get().MailSetSMTPMessageID(m_hNote64, null, messageId, (short) (NotesConstants.MAXPATH & 0xffff)); + } + else { + setMsgIdResult = NotesNativeAPI32.get().MailSetSMTPMessageID(m_hNote32, null, messageId, (short) (NotesConstants.MAXPATH & 0xffff)); + } + NotesErrorUtils.checkResult(setMsgIdResult); + + String messageIdStr = NotesStringUtils.fromLMBCS(messageId, -1); + replaceItemValue(NotesConstants.MAIL_ID_ITEM, messageIdStr); + + // we save the original note, not the new one + update(); + } + + // now we can kill the temp note and reset + tmpNote.recycle(); + } + + /** + * copy relevant subform items + * + * @param formNote source note + * @param tmpNote target note + */ + private void copySubformItems(NotesNote formNote, NotesNote tmpNote) { + checkHandle(); + if (m_parentDb.isRecycled()) { + throw new NotesError("Parent DB is recycled"); + } + + List exclude_list = Arrays.asList( + NotesConstants.DESIGN_CLASS, + NotesConstants.DESIGN_FLAGS, + NotesConstants.FIELD_UPDATED_BY, + NotesConstants.ITEM_NAME_TEMPLATE, + NotesConstants.FIELD_TITLE, + NotesConstants.ITEM_NAME_DOCUMENT + ); + + /* If the form doesn't contain a subform name list, then there's nothing to do */ + if (!formNote.hasItem(NotesConstants.SUBFORM_ITEM_NAME)) { + return; + } + + // get the list, iterate over the subform names + List subformNames = formNote.getItemValueStringList(NotesConstants.SUBFORM_ITEM_NAME); + for (int i = 0; i < subformNames.size(); i++) { + String subformname = subformNames.get(i); + Memory subformnameMem = NotesStringUtils.toLMBCS(subformname, true); + + if (NotesNativeAPI.get().StoredFormHasSubformToken(subformnameMem)) { + continue; + } + + PointerByReference ppName = new PointerByReference(); + ShortByReference pNameLen = new ShortByReference(); + PointerByReference ppAlias = new PointerByReference(); + ShortByReference pAliasLen = new ShortByReference(); + + NotesNativeAPI.get().DesignGetNameAndAlias(subformnameMem, + ppName, pNameLen, ppAlias, pAliasLen); + + Pointer subformaliasMem; + short subformaliasLen; + + if (Short.toUnsignedInt(pAliasLen.getValue()) > 0) { + subformaliasMem = ppAlias.getValue(); + subformaliasLen = pAliasLen.getValue(); + } + else { + subformaliasMem = ppName.getValue(); + subformaliasLen = pNameLen.getValue(); + } + String subformalias = NotesStringUtils.fromLMBCS(subformaliasMem, Short.toUnsignedInt(subformaliasLen)); + + Memory designPatternMem = NotesStringUtils.toLMBCS(NotesConstants.DFLAGPAT_SUBFORM_ALL_VERSIONS, true); + + IntByReference fnid = new IntByReference(); + + short lkDesignResult; + if (PlatformUtils.is64Bit()) { + lkDesignResult = NotesNativeAPI64.get().DesignLookupNameFE(m_parentDb.getHandle64(), NotesConstants.NOTE_CLASS_FORM, + designPatternMem, subformaliasMem, subformaliasLen, NotesConstants.DGN_ONLYSHARED, + fnid, null, null, null); + } + else { + lkDesignResult = NotesNativeAPI32.get().DesignLookupNameFE(m_parentDb.getHandle32(), NotesConstants.NOTE_CLASS_FORM, + designPatternMem, subformaliasMem, subformaliasLen, NotesConstants.DGN_ONLYSHARED, + fnid, null, null, null); + } + + if (lkDesignResult!=0) { + /* Try private. */ + if (PlatformUtils.is64Bit()) { + lkDesignResult = NotesNativeAPI64.get().DesignLookupNameFE(m_parentDb.getHandle64(), NotesConstants.NOTE_CLASS_FORM, + designPatternMem, subformaliasMem, subformaliasLen, NotesConstants.DGN_ONLYPRIVATE, + fnid, null, null, null); + } + else { + lkDesignResult = NotesNativeAPI32.get().DesignLookupNameFE(m_parentDb.getHandle32(), NotesConstants.NOTE_CLASS_FORM, + designPatternMem, subformaliasMem, subformaliasLen, NotesConstants.DGN_ONLYPRIVATE, + fnid, null, null, null); + } + } + + if (lkDesignResult!=0) { + continue; + } + + try { + NotesNote subformNote = m_parentDb.openNoteById(fnid.getValue(), EnumSet.of(OpenNote.CACHE)); + if (subformNote!=null) { + copyFormItems(subformNote, tmpNote, exclude_list, (short) ((i+2) & 0xffff), subformname); + } + } + catch (NotesError e) { + throw new NotesError(e.getId(), "Error opening subform "+subformalias, e); + } + } + } + + /** + * copy specified items from form when mailing + * + * @param formNote form note + * @param tmpNote target note + * @param excludeList exclude list of item names + */ + private void copyFormItems(NotesNote formNote, NotesNote tmpNote, List excludeList) { + copyFormItems(formNote, tmpNote, excludeList, (short) 0, null); + } + + /** + * copy specified items from form when mailing + * + * @param formNote form note + * @param tmpNote target note + * @param excludeList exclude list of item names + * @param namemod counter + * @param subformname subform name or null + */ + private void copyFormItems(NotesNote formNote, NotesNote tmpNote, List excludeList, + short namemod, String subformname) { + checkHandle(); + + // table of items which get renamed, if this is a subform copy + List rename_list = Arrays.asList( + NotesConstants.FORM_SCRIPT_ITEM_NAME, + NotesConstants.DOC_SCRIPT_ITEM, + NotesConstants.DOC_SCRIPT_NAME, + NotesConstants.DOC_ACTION_ITEM + + ); + + /* These are the object-code item names, derived + from the ones above (prepended '$', appended "_O") */ + List rename_list_special = Arrays.asList( + "$" + NotesConstants.FORM_SCRIPT_ITEM_NAME + "_O", + "$" + NotesConstants.DOC_SCRIPT_ITEM + "_O" + ); + + /* Copy all items beginning with '$' from the form note to + * the current note. Certain item names are skipped for the + * form ($FLAGS, $CLASS, $UPDATEDBY) and for subforms (indicated by + * namemod > 0) ($TITLE, $BODY). + * + * If the "namemod" argument is > 0, then we also have to make + * the new item name different: append the integer to the name + * again, for selected item names. + */ + formNote.getItems((item, loop) -> { + String itemName = item.getName(); + if (itemName.startsWith("$")) { + boolean exclude = false; + + if (ListUtil.containsIgnoreCase(excludeList, itemName)) { + exclude = true; + } + else if (NotesConstants.ITEM_NAME_NOTE_SIGNATURE.equals(itemName)) { + exclude = true; + } + + if (!exclude) { + /* If the item's name is not being modified, then use the + easy ItemCopy call. If it is, though, we have to do a + bit more work. If this is a subform, check the rename + list to see if it really is getting renamed. + + Note that there are script object-code items with the + same name as the source-code items, but with an appended + "_O". If we find one of those, then we have to specially + rename it, the number goes before the _O, not after + */ + + boolean rename = false; + boolean rename_special = false; + boolean rename_signature = false; + + String itemname2 = ""; + + if (NotesConstants.ITEM_NAME_NOTE_SIGNATURE.equalsIgnoreCase(itemName)) { + rename = true; + rename_signature = true; + + if (namemod == 0) { + itemname2 = NotesConstants.ITEM_NAME_NOTE_STOREDFORM_SIG; + } + else { + itemname2 = NotesConstants.ITEM_NAME_NOTE_STOREDFORM_SIG_PREFIX + subformname; + if (itemname2.length() > NotesConstants.MAXPATH) { + itemname2 = itemname2.substring(0, NotesConstants.MAXPATH); + } + } + + } + + // if (namemod && + if (namemod>0 && !rename_signature) { + if (ListUtil.containsIgnoreCase(rename_list, itemName)) { + rename = true; + } + else if (ListUtil.containsIgnoreCase(rename_list_special, itemName)) { // check for special + rename = true; + rename_special = true; + } + } + + // "special" rename? + if (rename_special) { + itemname2 = itemName.substring(0, itemName.length()-2); // trim _O + itemname2 += Short.toString(namemod); + } + else if (!rename_signature) { + itemname2 = itemName + Short.toString(namemod); + } + + if (rename) { + //we need to check if this call does the same as the C code below + item.copyToNote(tmpNote, itemname2, false); + } + else { + item.copyToNote(tmpNote, false); + } + } + } + }); + } + + /** + * detect any MIME_PART items not named "Body"; if not found, detect any TYPE_MIME_PART item named "Body" + * + * @param foundNonBodyMIME returns {@link Boolean#TRUE} if there are TYPE_MIME_PART items with a different name than "body" + * @param foundBodyMIME returns {@link Boolean#TRUE} if there are TYPE_MIME_PART items with the name than "body" + */ + private void searchForNonBodyMIME(Ref foundNonBodyMIME, Ref foundBodyMIME) { + foundNonBodyMIME.set(Boolean.FALSE); + foundBodyMIME.set(Boolean.FALSE); + + /* Optimization: assume by this point that if there is no $NoteHasNativeMIME item, then + * there aren't any MIME_PART items at all. + */ + if (!hasItem(NotesConstants.ITEM_IS_NATIVE_MIME)) { + return; + } + + /* Finally, scan all the items, looking for non-"Body" item of TYPE_MIME_PART */ + getItems((item, loop) -> { + if (item.getType() == NotesItem.TYPE_MIME_PART) { + String itemName = item.getName(); + if (NotesConstants.MAIL_BODY_ITEM.equalsIgnoreCase(itemName)) { + // don't stop here; finding MIME "Body" is secondary to finding MIME non-"Body"s + foundBodyMIME.set(Boolean.TRUE); + } + else { + foundNonBodyMIME.set(Boolean.TRUE); + loop.stop(); + } + } + }); + } } diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/constants/OpenNote.java b/domino-jna/src/main/java/com/mindoo/domino/jna/constants/OpenNote.java index e1112cc4..a6bdf501 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/constants/OpenNote.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/constants/OpenNote.java @@ -69,6 +69,16 @@ public enum OpenNote { * NSFNoteOpenExt. You do not need to set this flag when calling NSFDbCopyNoteExt. */ WITH_FOLDERS, + /** If specified, the open will check to see if this note had already been read and + * saved in memory. If not, and the database is server based, we will also check + * the on-disk cache. If the note is not found, it is cached in memory and at some + * time in the future commited to a local on disk cache.
+ *
+ * The notes are guaranteed to be as up to date as the last time NSFValidateNoteCache was called. + * Minimally, this should be called the 1st time a database is opened prior to specifying + * this flag. */ + CACHE, + /** * Converts items of type {@link NotesItem#TYPE_RFC822_TEXT} to {@link NotesItem#TYPE_TEXT} * and {@link NotesItem#TYPE_TIME}. If not set, we leave the items in their native format. diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI.java index 25c19823..9aa40701 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI.java @@ -473,4 +473,8 @@ public short NSFDbDelete( Memory PathName ); + public void DesignGetNameAndAlias(Memory pString, PointerByReference ppName, ShortByReference pNameLen, PointerByReference ppAlias, ShortByReference pAliasLen); + + public boolean StoredFormHasSubformToken(Memory pString); + } diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI32.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI32.java index eaa1295a..0463f95d 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI32.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI32.java @@ -1775,4 +1775,31 @@ public short NSFDbOpenTemplateExtended( NotesTimeDateStruct retDataModified, NotesTimeDateStruct retNonDataModified); + public short NSFNoteCreateClone (int hSrcNote, IntByReference rethDstNote); + + public short NSFNoteReplaceItems (int hSrcNote, int hDstNote, ShortByReference pwRetItemReplaceCount, boolean fAllowDuplicates); + + public short StoredFormAddItems (int hSrcDbHandle, int hSrcNote, int hDstNote, boolean bDoSubforms, int dwFlags); + + public short StoredFormRemoveItems(int hNote, int dwFlags); + + public short MailNoteJitEx2(Pointer vpRunCtx, int hNote, short wMailFlags, IntByReference retdwRecipients, + short jitflag, short wMailNoteFlags, NotesCallbacks.b32_FPMailNoteJitEx2CallBack vCallBack, Pointer vCallBackCtx); + + public short MailSetSMTPMessageID(int hNote, Memory domain, Memory string, short stringLength); + + public short NSFDbReopenWithFullAccess(int hDb, IntByReference hReopenedDb); + + /* This is exactly the same as lookup name BE, except it will use the + cache of the design collection as known to the client. This is safe + to use outside the client since it will map to the BE code. Using this + version will only be as up to date as the last time the design was + fetched for the client. This was added explicitly to avoid cases of + backend code executing in their world where backend changes to design + things was not seen immediately. */ + public short DesignLookupNameFE (int hDB, short wClass, Pointer szFlagsPattern, Pointer szName, + short wNameLen, int flags, + IntByReference retNoteID, IntByReference retbIsPrivate, + NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC OpenCloseRoutine, Pointer Ctx); + } diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI64.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI64.java index 998eb577..422c5310 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI64.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/INotesNativeAPI64.java @@ -1782,4 +1782,32 @@ public short NSFDbOpenTemplateExtended( NotesTimeDateStruct retDataModified, NotesTimeDateStruct retNonDataModified); + public short NSFNoteCreateClone (long hSrcNote, LongByReference rethDstNote); + + public short NSFNoteReplaceItems (long hSrcNote, long hDstNote, ShortByReference pwRetItemReplaceCount, boolean fAllowDuplicates); + + public short StoredFormAddItems (long hSrcDbHandle, long hSrcNote, long hDstNote, boolean bDoSubforms, int dwFlags); + + public short StoredFormRemoveItems(long hNote, int dwFlags); + + public short MailNoteJitEx2(Pointer vpRunCtx, long hNote, short wMailFlags, IntByReference retdwRecipients, + short jitflag, short wMailNoteFlags, NotesCallbacks.b64_FPMailNoteJitEx2CallBack vCallBack, Pointer vCallBackCtx); + + public short MailSetSMTPMessageID(long hNote, Memory domain, Memory string, short stringLength); + + public short NSFDbReopenWithFullAccess(long hDb, LongByReference hReopenedDb); + + /* This is exactly the same as lookup name BE, except it will use the + cache of the design collection as known to the client. This is safe + to use outside the client since it will map to the BE code. Using this + version will only be as up to date as the last time the design was + fetched for the client. This was added explicitly to avoid cases of + backend code executing in their world where backend changes to design + things was not seen immediately. */ + public short DesignLookupNameFE (long hDB, short wClass, Pointer szFlagsPattern, Pointer szName, + short wNameLen, int flags, + IntByReference retNoteID, IntByReference retbIsPrivate, + NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC OpenCloseRoutine, Pointer Ctx); + + } diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesCallbacks.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesCallbacks.java index 5915b090..b1a7b508 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesCallbacks.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesCallbacks.java @@ -227,4 +227,16 @@ interface b32_NSFDbNamedObjectEnumPROC extends Callback { short invoke(int hDB, Pointer param, short nameSpace, Pointer name, short nameLength, IntByReference objectID, NotesTimeDateStruct entryTime); } + interface b64_FPMailNoteJitEx2CallBack extends Callback { + short invoke(long hdl, Pointer ptr1, Pointer ptr2); + } + + interface b32_FPMailNoteJitEx2CallBack extends Callback { + short invoke(int hdl, Pointer ptr1, Pointer ptr2); + } + + interface DESIGN_COLL_OPENCLOSE_PROC extends Callback { + short invoke(int dwFlags, Pointer phColl, Pointer ctx); + } + } diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesConstants.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesConstants.java index 22d30c76..7481085b 100755 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesConstants.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesConstants.java @@ -323,6 +323,14 @@ the default notes (for efficient access to them). Whenever a note public static final short OPEN_RESPONSE_ID_TABLE = 0x1000; /** Include folder objects - default is not to */ public static final int OPEN_WITH_FOLDERS = 0x00020000; + /** If specified, the open will check to see if this note had already been read and + * saved in memory. If not, and the database is server based, we will also check + * the on-disk cache. If the note is not found, it is cached in memory and at some + * time in the future commited to a local on disk cache. + * The notes are guaranteed to be as up to date as the last time NSFValidateNoteCache was called.# + * Minimally, this should be called the 1st time a database is opened prior to specifying + * this flag. */ + public static final int OPEN_CACHE = 0x00100000; /** If set, leave TYPE_RFC822_TEXT items in native format. Otherwise, convert to TYPE_TEXT/TYPE_TIME. */ public static final int OPEN_RAW_RFC822_TEXT = 0x01000000; @@ -3736,4 +3744,160 @@ compatibility, outputs it to disk at Save() time /* Note is private and is located in the database */ public int DESIGN_TYPE_PRIVATE_DATABASE = 1; + /* wMailNoteFlags -- for extended control via MailNoteJitEx */ + + /* mail the note if there is at least one recipient, i.e. To, CC, or BCC */ + public short MAILNOTE_ANYRECIPIENT = 0x0001; + /* enabled logging */ + public short MAIL_JIT_LOG = 0x0002; + + /* wMailNoteFlags -- for extended control via MailNoteJitEx2 */ + + /* caller is enforcing OSGetEnvironmentInt(SECUREMAIL) ... don't force MSN_SIGN OR MSN_SEAL */ + public short MAILNOTE_NO_SECUREMAIL_MODE = 0x0004; + /* use local mail.box, regardless of LOCINFO_REALMAILSERVER or LOCINFO_MAILSERVER setting. */ + public short MAILNOTE_USELOCALMAILBOX = 0x0008; + /* don't use $$LNABHAS* in place of actual cert */ + public short MAILNOTE_NO_LNAB_ENTRIES = 0x0010; + /* don't have NAMELookup use local directories */ + public short MAILNOTE_NO_SEARCH_LOCAL_DIRECTORIES = 0x0020; + /* if recips only have Notes certs, do Notes encryption of MIME message */ + public short MAILNOTE_NOTES_ENCRYPT_MIME = 0x0040; + /* message is in mime format */ + public short MAILNOTE_MIMEBODY = 0x0080; + /* use X509 cert if it's the only one found */ + public short MAILNOTE_CANUSEX509 = 0x0100; + public short MAILNOTE_SKIP_LOOKUP = 0x0200; + + /* mail note that is not a jit canidate*/ + public short MAIL_NO_JIT = 0; + /* mail a JIT canidate note*/ + public short MAIL_JIT = 1; + /* mail a miem message that is not a jit canidate*/ + public short MAIL_MIME_NO_JIT = 2; + /* mail a note that is not a JIT, but caller has set recipient's field */ + public short MAIL_NO_JIT_RECIPIENTS_DONE = 3; + + /* Query for Sign/Seal */ + public short MSN_QUERY = 0x0001; + /* Sign */ + public short MSN_SIGN = 0x0002; + /* Seal */ + public short MSN_SEAL = 0x0004; + /* Use results of previous query */ + public short MSN_PREVQUERY = 0x0008; + /* Must send to North American */ + public short MSN_AMERICAN_ONLY = 0x0010; + + /* license holders. */ + + /* Recipient must have valid */ + public short MSN_PUBKEY_ONLY = 0x0020; + /* Sending a receit message. */ + public short MSN_RECEIPT = 0x0040; + /* The dialog is for a DDE request */ + public short MSN_DDEDIALOG = 0x0080; + /* Don't allow mail encryption */ + public short MSN_NOSEAL = 0x0100; + /* Used by alternate mail */ + public short MSN_FWDASATT = 0x0200; + + /* The mailer should process the */ + /* note, skip recipient work */ + /* and prompt the user for */ + /* addressing. */ + + /* Disregard all other flags */ + public short MSN_ADDRESS_ONLY = 0x0400; + + /* and refresh the mail addresses */ + /* via lookup */ + + /* Don't lookup the supplied names */ + public short MSN_NOLOOKUP = 0x0800; + /* MailForwardNoteNoEdit only */ + + /* Used by alternate mail */ + public short MSN_FWDASTEXT = 0x1000; + /* The mailer should process the */ + /* note, skip recipient work */ + /* and prompt the user for */ + /* addressing. */ + + /* Indicates that the From field has */ + /* already been set up and that the */ + /* mailer should not slam it with the */ + /* user name. This is used by agents */ + /* running on the server */ + public short MSN_FROMOVERRIDE = 0x2000; + /* deposit in smtp.box instead of mail.box */ + public short MSN_SMTP_MAILBOX = 0X4000; + + /* 2 pass mailer */ + public short MSN_2PASSMAILER = (short) (0x8000 & 0xffff); + + public String DESIGN_CLASS = "$Class"; + + public String FIELD_UPDATED_BY = "$UpdatedBy"; + public String FIELD_FORM = "Form"; + + /* form item to hold form CD */ + public String ITEM_NAME_TEMPLATE = "$Body"; + + /* SendTo item name */ + public String MAIL_SENDTO_ITEM = "SendTo"; + /* CopyTo item name */ + public String MAIL_COPYTO_ITEM = "CopyTo"; + /* Blind copy to item name */ + public String MAIL_BLINDCOPYTO_ITEM = "BlindCopyTo"; + + public short DGN_ONLYSHARED = 0x0040; + public short DGN_ONLYPRIVATE = 0x0080; + + /* display things editable with dialog box; no version filtering (for design) */ + public String DFLAGPAT_VIEWFORM_ALL_VERSIONS = "-FQMUGXWy#i:|@K;g~%z^}"; + + /* If this field exists in a mail note, it means that */ + /* mail message was created by an agent. */ + public String ASSIST_MAIL_ITEM = "$AssistMail"; + + /* indicates if message was auto generated */ + public String MAIL_ITEM_AUTOSUBMITTED = "Auto-submitted"; + /* value for MAIL_ITEM_AUTOSUBMITTED */ + public String MAIL_AUTOGENERATED = "auto-generated"; + + /* From item name */ + public String MAIL_FROM_ITEM = "From"; + + /* Posted date item name */ + public String MAIL_POSTEDDATE_ITEM = "PostedDate"; + + /* Unique ID of this message */ + public String MAIL_ID_ITEM = "$MessageID"; + + public String ITEM_IS_NATIVE_MIME = "$NoteHasNativeMIME"; + + /* Body item name */ + public String MAIL_BODY_ITEM = "Body"; + + public String FORM_SCRIPT_ITEM_NAME = "$$FormScript"; + public String DOC_SCRIPT_ITEM = "$Script"; + public String DOC_SCRIPT_NAME = "$$ScriptName"; + public String DOC_ACTION_ITEM = "$$FormAction"; + + public String ITEM_NAME_NOTE_SIGNATURE = "$Signature"; + /* stored form signature */ + public String ITEM_NAME_NOTE_STOREDFORM_SIG = "$SIG$Form"; + /* stored form and subform signature prefix - followed by either $FORM or the subform name*/ + public String ITEM_NAME_NOTE_STOREDFORM_SIG_PREFIX = "$SIG"; + + public String FIELD_TITLE = "$TITLE"; + /* document header info */ + public String ITEM_NAME_DOCUMENT = "$Info"; + public String SUBFORM_ITEM_NAME = "$SubForms"; + + /* only subforms; no version filtering */ + public String DFLAGPAT_SUBFORM_ALL_VERSIONS = "+U"; + + } \ No newline at end of file diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI.java index a0ad546a..575b9bab 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI.java @@ -801,4 +801,9 @@ public native short NSFDbDelete( Memory PathName ); + public native void DesignGetNameAndAlias(Memory pString, PointerByReference ppName, ShortByReference pNameLen, PointerByReference ppAlias, ShortByReference pAliasLen); + + @Override + public native boolean StoredFormHasSubformToken(Memory pString); + } diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI32.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI32.java index 6978d47a..498800a4 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI32.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI32.java @@ -4,7 +4,9 @@ import com.mindoo.domino.jna.gc.NotesGC; import com.mindoo.domino.jna.internal.NotesCallbacks.ABORTCHECKPROC; import com.mindoo.domino.jna.internal.NotesCallbacks.ACLENTRYENUMFUNC; +import com.mindoo.domino.jna.internal.NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC; import com.mindoo.domino.jna.internal.NotesCallbacks.OSSIGMSGPROC; +import com.mindoo.domino.jna.internal.NotesCallbacks.b32_FPMailNoteJitEx2CallBack; import com.mindoo.domino.jna.internal.NotesCallbacks.b32_NSFDbNamedObjectEnumPROC; import com.mindoo.domino.jna.internal.NotesCallbacks.b32_NSFGetAllFolderChangesCallback; import com.mindoo.domino.jna.internal.structs.NIFFindByKeyContextStruct; @@ -1470,5 +1472,33 @@ public native short NSFDbCopy( public native short NSFDbOpenTemplateExtended(Memory PathName, short Options, int hNames, NotesTimeDateStruct ModifiedTime, IntByReference rethDB, NotesTimeDateStruct retDataModified, NotesTimeDateStruct retNonDataModified); + + @Override + public native short NSFNoteCreateClone(int hSrcNote, IntByReference rethDstNote); + + @Override + public native short NSFNoteReplaceItems(int hSrcNote, int hDstNote, ShortByReference pwRetItemReplaceCount, + boolean fAllowDuplicates); + + @Override + public native short StoredFormAddItems(int hSrcDbHandle, int hSrcNote, int hDstNote, boolean bDoSubforms, int dwFlags); + + @Override + public native short StoredFormRemoveItems(int hNote, int dwFlags); + + @Override + public native short MailNoteJitEx2(Pointer vpRunCtx, int hNote, short wMailFlags, IntByReference retdwRecipients, + short jitflag, short wMailNoteFlags, b32_FPMailNoteJitEx2CallBack vCallBack, Pointer vCallBackCtx); + + @Override + public native short MailSetSMTPMessageID(int hNote, Memory domain, Memory string, short stringLength); + + @Override + public native short NSFDbReopenWithFullAccess(int hDb, IntByReference hReopenedDb); + + @Override + public native short DesignLookupNameFE(int hDB, short wClass, Pointer szFlagsPattern, Pointer szName, short wNameLen, + int flags, IntByReference retNoteID, IntByReference retbIsPrivate, + DESIGN_COLL_OPENCLOSE_PROC OpenCloseRoutine, Pointer Ctx); } diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI64.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI64.java index c01b7bd7..94b1a0f2 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI64.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/NotesNativeAPI64.java @@ -4,7 +4,9 @@ import com.mindoo.domino.jna.gc.NotesGC; import com.mindoo.domino.jna.internal.NotesCallbacks.ABORTCHECKPROC; import com.mindoo.domino.jna.internal.NotesCallbacks.ACLENTRYENUMFUNC; +import com.mindoo.domino.jna.internal.NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC; import com.mindoo.domino.jna.internal.NotesCallbacks.OSSIGMSGPROC; +import com.mindoo.domino.jna.internal.NotesCallbacks.b64_FPMailNoteJitEx2CallBack; import com.mindoo.domino.jna.internal.NotesCallbacks.b64_NSFDbNamedObjectEnumPROC; import com.mindoo.domino.jna.internal.NotesCallbacks.b64_NSFGetAllFolderChangesCallback; import com.mindoo.domino.jna.internal.structs.NIFFindByKeyContextStruct; @@ -1483,6 +1485,34 @@ public native short NSFDbCopy(long hSrcDB, long hDstDB, public native short NSFDbOpenTemplateExtended(Memory PathName, short Options, long hNames, NotesTimeDateStruct ModifiedTime, LongByReference rethDB, NotesTimeDateStruct retDataModified, NotesTimeDateStruct retNonDataModified); + + @Override + public native short NSFNoteCreateClone(long hSrcNote, LongByReference rethDstNote); + + @Override + public native short NSFNoteReplaceItems(long hSrcNote, long hDstNote, ShortByReference pwRetItemReplaceCount, + boolean fAllowDuplicates); + + @Override + public native short StoredFormAddItems(long hSrcDbHandle, long hSrcNote, long hDstNote, boolean bDoSubforms, int dwFlags); + + @Override + public native short StoredFormRemoveItems(long hNote, int dwFlags); + + @Override + public native short MailNoteJitEx2(Pointer vpRunCtx, long hNote, short wMailFlags, IntByReference retdwRecipients, + short jitflag, short wMailNoteFlags, b64_FPMailNoteJitEx2CallBack vCallBack, Pointer vCallBackCtx); + + @Override + public native short MailSetSMTPMessageID(long hNote, Memory domain, Memory string, short stringLength); + + @Override + public native short NSFDbReopenWithFullAccess(long hDb, LongByReference hReopenedDb); + + @Override + public native short DesignLookupNameFE(long hDB, short wClass, Pointer szFlagsPattern, Pointer szName, short wNameLen, + int flags, IntByReference retNoteID, IntByReference retbIsPrivate, + DESIGN_COLL_OPENCLOSE_PROC OpenCloseRoutine, Pointer Ctx); } diff --git a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/Win32NotesCallbacks.java b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/Win32NotesCallbacks.java index f0962aac..e1e903fb 100644 --- a/domino-jna/src/main/java/com/mindoo/domino/jna/internal/Win32NotesCallbacks.java +++ b/domino-jna/src/main/java/com/mindoo/domino/jna/internal/Win32NotesCallbacks.java @@ -67,4 +67,8 @@ interface NSFPROFILEENUMPROCWin32 extends NotesCallbacks.b32_NSFPROFILEENUMPROC, interface NSFDbNamedObjectEnumPROCWin32 extends NotesCallbacks.b32_NSFDbNamedObjectEnumPROC, StdCallCallback {}; + interface FPMailNoteJitEx2CallBackWin32 extends NotesCallbacks.b32_FPMailNoteJitEx2CallBack, StdCallCallback {}; + + interface DESIGN_COLL_OPENCLOSE_PROCWin32 extends NotesCallbacks.DESIGN_COLL_OPENCLOSE_PROC, StdCallCallback {}; + }