How to Add and Remove MIME attachments correctly
I am adding MIME attachments to a document like this
try{
var d = database.getView("Main").getFirstDocument()
var it = d.getFirstItem("Body")
var att:NotesEmbeddedObject = it.getEmbeddedObject("mydoc.docx")
var streamDOC:NotesStream = session.createStream()
streamDOC.setContents(att.getInputStream())
var newd;
newd = database.getView("NewD").getFirstDocument()
if(newd==null){
newd = database.createDocument()
newd.replaceItemValue("Form","Main")
var me = newd.createMIMEEntity("Body")
}else{
var me = newd.getMIMEEntity("Body")
}
var filename = "test.pdf"
var mc = me.createChildEntity();
var he = mc.createHeader("Content-Disposition")
he.setHeaderVal("attachment; filename="" + filename + """);
he = mc.createHeader("Content-ID");
he.setHeaderVal( "<" + filename + ">" );
mc.setContentFromBytes(streamDOC, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", NotesMIMEEntity.ENC_IDENTITY_8BIT);
newd.save()
print("success")
}catch(e){
print("fail " + e)
}
and in a repeat I provide a delete button
var eo = nd.getDocument().getAttachment(att)
eo.remove()
nd.save()
the attachment are removed from the document, in Ytria I can see that the $FILE items are removed but not the BODY items. the problem with this is that if I add a new attachment to the same document all the attachments I removed previously come back
This is how the document looks before removing the attachments.
The file size here is unfortnuately 0Kb because I used the wrong screenshot. from the beginnin all $File items have correct size
This is how the document look after I removed the attachments (using the script above)
This is what the document look like after I add one attachment (using the script above) after I removed them
- Could I be doing something wrong when adding or removing the attachments? (see
script) - It does not seem to matter if the Body field has the "store
content as MIME" option set or not - see also this question
How to Add and Remove attachments using MIME
xpages attachment mime
add a comment |
I am adding MIME attachments to a document like this
try{
var d = database.getView("Main").getFirstDocument()
var it = d.getFirstItem("Body")
var att:NotesEmbeddedObject = it.getEmbeddedObject("mydoc.docx")
var streamDOC:NotesStream = session.createStream()
streamDOC.setContents(att.getInputStream())
var newd;
newd = database.getView("NewD").getFirstDocument()
if(newd==null){
newd = database.createDocument()
newd.replaceItemValue("Form","Main")
var me = newd.createMIMEEntity("Body")
}else{
var me = newd.getMIMEEntity("Body")
}
var filename = "test.pdf"
var mc = me.createChildEntity();
var he = mc.createHeader("Content-Disposition")
he.setHeaderVal("attachment; filename="" + filename + """);
he = mc.createHeader("Content-ID");
he.setHeaderVal( "<" + filename + ">" );
mc.setContentFromBytes(streamDOC, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", NotesMIMEEntity.ENC_IDENTITY_8BIT);
newd.save()
print("success")
}catch(e){
print("fail " + e)
}
and in a repeat I provide a delete button
var eo = nd.getDocument().getAttachment(att)
eo.remove()
nd.save()
the attachment are removed from the document, in Ytria I can see that the $FILE items are removed but not the BODY items. the problem with this is that if I add a new attachment to the same document all the attachments I removed previously come back
This is how the document looks before removing the attachments.
The file size here is unfortnuately 0Kb because I used the wrong screenshot. from the beginnin all $File items have correct size
This is how the document look after I removed the attachments (using the script above)
This is what the document look like after I add one attachment (using the script above) after I removed them
- Could I be doing something wrong when adding or removing the attachments? (see
script) - It does not seem to matter if the Body field has the "store
content as MIME" option set or not - see also this question
How to Add and Remove attachments using MIME
xpages attachment mime
add a comment |
I am adding MIME attachments to a document like this
try{
var d = database.getView("Main").getFirstDocument()
var it = d.getFirstItem("Body")
var att:NotesEmbeddedObject = it.getEmbeddedObject("mydoc.docx")
var streamDOC:NotesStream = session.createStream()
streamDOC.setContents(att.getInputStream())
var newd;
newd = database.getView("NewD").getFirstDocument()
if(newd==null){
newd = database.createDocument()
newd.replaceItemValue("Form","Main")
var me = newd.createMIMEEntity("Body")
}else{
var me = newd.getMIMEEntity("Body")
}
var filename = "test.pdf"
var mc = me.createChildEntity();
var he = mc.createHeader("Content-Disposition")
he.setHeaderVal("attachment; filename="" + filename + """);
he = mc.createHeader("Content-ID");
he.setHeaderVal( "<" + filename + ">" );
mc.setContentFromBytes(streamDOC, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", NotesMIMEEntity.ENC_IDENTITY_8BIT);
newd.save()
print("success")
}catch(e){
print("fail " + e)
}
and in a repeat I provide a delete button
var eo = nd.getDocument().getAttachment(att)
eo.remove()
nd.save()
the attachment are removed from the document, in Ytria I can see that the $FILE items are removed but not the BODY items. the problem with this is that if I add a new attachment to the same document all the attachments I removed previously come back
This is how the document looks before removing the attachments.
The file size here is unfortnuately 0Kb because I used the wrong screenshot. from the beginnin all $File items have correct size
This is how the document look after I removed the attachments (using the script above)
This is what the document look like after I add one attachment (using the script above) after I removed them
- Could I be doing something wrong when adding or removing the attachments? (see
script) - It does not seem to matter if the Body field has the "store
content as MIME" option set or not - see also this question
How to Add and Remove attachments using MIME
xpages attachment mime
I am adding MIME attachments to a document like this
try{
var d = database.getView("Main").getFirstDocument()
var it = d.getFirstItem("Body")
var att:NotesEmbeddedObject = it.getEmbeddedObject("mydoc.docx")
var streamDOC:NotesStream = session.createStream()
streamDOC.setContents(att.getInputStream())
var newd;
newd = database.getView("NewD").getFirstDocument()
if(newd==null){
newd = database.createDocument()
newd.replaceItemValue("Form","Main")
var me = newd.createMIMEEntity("Body")
}else{
var me = newd.getMIMEEntity("Body")
}
var filename = "test.pdf"
var mc = me.createChildEntity();
var he = mc.createHeader("Content-Disposition")
he.setHeaderVal("attachment; filename="" + filename + """);
he = mc.createHeader("Content-ID");
he.setHeaderVal( "<" + filename + ">" );
mc.setContentFromBytes(streamDOC, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", NotesMIMEEntity.ENC_IDENTITY_8BIT);
newd.save()
print("success")
}catch(e){
print("fail " + e)
}
and in a repeat I provide a delete button
var eo = nd.getDocument().getAttachment(att)
eo.remove()
nd.save()
the attachment are removed from the document, in Ytria I can see that the $FILE items are removed but not the BODY items. the problem with this is that if I add a new attachment to the same document all the attachments I removed previously come back
This is how the document looks before removing the attachments.
The file size here is unfortnuately 0Kb because I used the wrong screenshot. from the beginnin all $File items have correct size
This is how the document look after I removed the attachments (using the script above)
This is what the document look like after I add one attachment (using the script above) after I removed them
- Could I be doing something wrong when adding or removing the attachments? (see
script) - It does not seem to matter if the Body field has the "store
content as MIME" option set or not - see also this question
How to Add and Remove attachments using MIME
xpages attachment mime
xpages attachment mime
edited Nov 22 '18 at 13:22
Thomas Adrian
asked Nov 22 '18 at 12:51
Thomas AdrianThomas Adrian
2,49422448
2,49422448
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
If you work with MIME methods to attach the file why not work with MIME methods to remove it as well?
I use my own framework so the following code might give you the impression to overcomplicate things but hopefully you should get the gist of it:
I have an enum that helps me navigate through the various MIME types. In this case you are dealing with ATTACHMENT
:
public enum MimeContentType {
ATTACHMENT("attachment") {
@Override
public boolean matches(String headers) {
int score = 0;
for (String header : headers) {
if (header.startsWith("Content-Disposition")) {
score++;
}
if (header.contains("attachment")) {
score++;
}
if (header.contains("filename")) {
score++;
}
if (score == 3) {
return true;
}
}
return false;
}
},
TEXT("text"),
TEXT_HTML("text/html"),
TEXT_PLAIN("text/plain");
private final String type;
private MimeContentType(String type) {
this.type = type;
}
public boolean matches(String headers) {
for (String header : headers) {
if (header.startsWith("Content-Type") && header.contains(type)) {
return true;
}
}
return false;
}
}
Then some helper classes:
@FunctionalInterface
public interface ThrowableConsumer<T> extends Consumer<T> {
@Override
default void accept(final T t) {
try {
acceptOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
void acceptOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableFunction<T, R> extends Function<T, R> {
@Override
default R apply(T t) {
try {
return applyOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
R applyOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowablePredicate<T> extends Predicate<T> {
@Override
default boolean test(T t) {
try {
return testOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
boolean testOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableSupplier<T> extends Supplier<T> {
@Override
default T get() {
try {
return getOrThrow();
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
T getOrThrow() throws Throwable;
}
public enum DominoUtil {
;
private static final Vector<String> MIME_FILTERED_HEADERS = new Vector<>();
static {
MIME_FILTERED_HEADERS.add("Content-Type");
MIME_FILTERED_HEADERS.add("Content-Disposition");
}
public static List<MIMEEntity> getMimeEntitiesByContentType(MIMEEntity entity,
MimeContentType contentType) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(contentType, "Content type cannot be null");
List<MIMEEntity> subentities = new ArrayList<>();
MIMEEntity nextEntity = null;
try {
nextEntity = entity.getNextEntity();
while (nextEntity != null) {
String entityFilteredHeaders = nextEntity
.getSomeHeaders(MIME_FILTERED_HEADERS, true)
.split("\n");
if (contentType.matches(entityFilteredHeaders)) {
subentities.add(nextEntity);
}
nextEntity = nextEntity.getNextEntity();
}
} finally {
DominoUtil.recycle(nextEntity);
}
return subentities;
}
public final static MIMEEntity getMimeEntity(Document doc, String itemName,
boolean createOnFail) throws NotesException {
if (itemName == null) {
throw new NullPointerException("Invalid MIME entity item name");
}
MIMEEntity mimeEntity = doc.getMIMEEntity(itemName);
if (mimeEntity == null) {
if (doc.hasItem(itemName)) {
doc.removeItem(itemName);
}
if (createOnFail) {
mimeEntity = doc.createMIMEEntity(itemName);
}
}
return mimeEntity;
}
public static Optional<String> getMimeEntityAttachmentFilename(MIMEEntity entity) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
return getMimeEntityHeaderValAndParams(
entity, (ThrowablePredicate<MIMEHeader>) h -> h.getHeaderVal().equals("attachment"))
.map(s -> {
Matcher m = Pattern.compile("filename=['"]?([^'"\s]+)").matcher(s);
m.find();
return m.group(1);
});
}
public static Optional<String> getMimeEntityHeaderValAndParams(
MIMEEntity entity, Predicate<MIMEHeader> matcher) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(matcher, "Matcher cannot be null");
Vector<?> headers = entity.getHeaderObjects();
try {
return headers
.stream()
.map(MIMEHeader.class::cast)
.filter(matcher)
.map((ThrowableFunction<MIMEHeader, String>) MIMEHeader::getHeaderValAndParams)
.findFirst();
} finally {
recycle(headers);
}
}
public static void recycle(Base... bases) {
for (Base base : bases) {
if (base != null) {
try {
base.recycle();
} catch (Exception e) {
// Do nothing
}
}
}
}
public static void recycle(Collection<? extends Object> objs) {
objs.stream()
.filter(o -> o instanceof Base)
.map(o -> (Base) o)
.forEach(DominoUtil::recycle);
}
}
Finally the method that would do the job:
public class Example {
public static void yourEntryPoint() {
try {
// The last param is just a way to create an attachment from text
// You have InputStream to pass along obviously
addAttachment(doc, "Body", "fake1.txt", "this is fake text1");
addAttachment(doc, "Body", "fake2.txt", "this is fake text2");
addAttachment(doc, "Body", "fake3.txt", "this is fake text3");
removeAttachment(doc, "Body", "fake2.txt");
removeAttachment(doc, "Body", "fake3.txt");
} catch (NotesException e) {
throw new RuntimeException(e);
}
}
private static void addAttachment(Document doc, String itemName, String fileName, String data)
throws NotesException {
MIMEEntity mimeEntity = null;
Stream stm = null;
try {
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
MIMEEntity attachmentEntity = null;
if (optAttEntity.isPresent()) {
attachmentEntity = optAttEntity.get();
} else {
attachmentEntity = mimeEntity.createChildEntity();
MIMEHeader header = attachmentEntity.createHeader("Content-Disposition");
header.setHeaderValAndParams("attachment; filename="" + fileName + """);
}
stm = doc.getParentDatabase().getParent().createStream();
stm.writeText(data);
attachmentEntity.setContentFromBytes(stm,
"application/octet-stream",
MIMEEntity.ENC_IDENTITY_BINARY);
stm.close();
doc.closeMIMEEntities(true, itemName);
} finally {
DominoUtil.recycle(stm);
DominoUtil.recycle(mimeEntity);
}
}
private static void removeAttachment(Document doc, String itemName, String fileName)
throws NotesException {
MIMEEntity mimeEntity = null;
try {
// Get MIME entity
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
if (!optAttEntity.isPresent()) {
return;
}
optAttEntity.get().remove();
// Header cleaning on empty entity
if (mimeEntity.getFirstChildEntity() != null) {
doc.closeMIMEEntities(true, itemName);
} else {
mimeEntity.remove();
}
} finally {
DominoUtil.recycle(mimeEntity);
}
}
private static Optional<MIMEEntity> getAttachmentMimeEntity(MIMEEntity root, String fileName)
throws NotesException {
return DominoUtil
.getMimeEntitiesByContentType(root, MimeContentType.ATTACHMENT)
.stream()
.filter((ThrowablePredicate<MIMEEntity>) mime -> {
Optional<String> opt = DominoUtil.getMimeEntityAttachmentFilename(mime);
return opt.isPresent() && opt.get().equals(fileName);
})
.findFirst();
}
}
thanks, that could be helpful but your code is not complete public static Map<MimeContentType, List<MIMEEntity>> getMimeEntities(MIMEEntity entity, MimeContentType... contentTypes)
– Thomas Adrian
Nov 22 '18 at 16:49
Sorry, I don’t understand what you mean by that. I put the code together by stripping all the rest of the code out but what remained seems complete to me. Am I blind?
– shillem
Nov 22 '18 at 17:07
I get compile errors.
– Thomas Adrian
Nov 22 '18 at 17:12
Ok, for sure I left out the import statements. What are the errors? Do you use iava8 or 6?
– shillem
Nov 22 '18 at 17:14
No, look at the method signature i showed in the comment. I am using DDE10
– Thomas Adrian
Nov 22 '18 at 17:27
|
show 4 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53431447%2fhow-to-add-and-remove-mime-attachments-correctly%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you work with MIME methods to attach the file why not work with MIME methods to remove it as well?
I use my own framework so the following code might give you the impression to overcomplicate things but hopefully you should get the gist of it:
I have an enum that helps me navigate through the various MIME types. In this case you are dealing with ATTACHMENT
:
public enum MimeContentType {
ATTACHMENT("attachment") {
@Override
public boolean matches(String headers) {
int score = 0;
for (String header : headers) {
if (header.startsWith("Content-Disposition")) {
score++;
}
if (header.contains("attachment")) {
score++;
}
if (header.contains("filename")) {
score++;
}
if (score == 3) {
return true;
}
}
return false;
}
},
TEXT("text"),
TEXT_HTML("text/html"),
TEXT_PLAIN("text/plain");
private final String type;
private MimeContentType(String type) {
this.type = type;
}
public boolean matches(String headers) {
for (String header : headers) {
if (header.startsWith("Content-Type") && header.contains(type)) {
return true;
}
}
return false;
}
}
Then some helper classes:
@FunctionalInterface
public interface ThrowableConsumer<T> extends Consumer<T> {
@Override
default void accept(final T t) {
try {
acceptOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
void acceptOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableFunction<T, R> extends Function<T, R> {
@Override
default R apply(T t) {
try {
return applyOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
R applyOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowablePredicate<T> extends Predicate<T> {
@Override
default boolean test(T t) {
try {
return testOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
boolean testOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableSupplier<T> extends Supplier<T> {
@Override
default T get() {
try {
return getOrThrow();
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
T getOrThrow() throws Throwable;
}
public enum DominoUtil {
;
private static final Vector<String> MIME_FILTERED_HEADERS = new Vector<>();
static {
MIME_FILTERED_HEADERS.add("Content-Type");
MIME_FILTERED_HEADERS.add("Content-Disposition");
}
public static List<MIMEEntity> getMimeEntitiesByContentType(MIMEEntity entity,
MimeContentType contentType) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(contentType, "Content type cannot be null");
List<MIMEEntity> subentities = new ArrayList<>();
MIMEEntity nextEntity = null;
try {
nextEntity = entity.getNextEntity();
while (nextEntity != null) {
String entityFilteredHeaders = nextEntity
.getSomeHeaders(MIME_FILTERED_HEADERS, true)
.split("\n");
if (contentType.matches(entityFilteredHeaders)) {
subentities.add(nextEntity);
}
nextEntity = nextEntity.getNextEntity();
}
} finally {
DominoUtil.recycle(nextEntity);
}
return subentities;
}
public final static MIMEEntity getMimeEntity(Document doc, String itemName,
boolean createOnFail) throws NotesException {
if (itemName == null) {
throw new NullPointerException("Invalid MIME entity item name");
}
MIMEEntity mimeEntity = doc.getMIMEEntity(itemName);
if (mimeEntity == null) {
if (doc.hasItem(itemName)) {
doc.removeItem(itemName);
}
if (createOnFail) {
mimeEntity = doc.createMIMEEntity(itemName);
}
}
return mimeEntity;
}
public static Optional<String> getMimeEntityAttachmentFilename(MIMEEntity entity) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
return getMimeEntityHeaderValAndParams(
entity, (ThrowablePredicate<MIMEHeader>) h -> h.getHeaderVal().equals("attachment"))
.map(s -> {
Matcher m = Pattern.compile("filename=['"]?([^'"\s]+)").matcher(s);
m.find();
return m.group(1);
});
}
public static Optional<String> getMimeEntityHeaderValAndParams(
MIMEEntity entity, Predicate<MIMEHeader> matcher) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(matcher, "Matcher cannot be null");
Vector<?> headers = entity.getHeaderObjects();
try {
return headers
.stream()
.map(MIMEHeader.class::cast)
.filter(matcher)
.map((ThrowableFunction<MIMEHeader, String>) MIMEHeader::getHeaderValAndParams)
.findFirst();
} finally {
recycle(headers);
}
}
public static void recycle(Base... bases) {
for (Base base : bases) {
if (base != null) {
try {
base.recycle();
} catch (Exception e) {
// Do nothing
}
}
}
}
public static void recycle(Collection<? extends Object> objs) {
objs.stream()
.filter(o -> o instanceof Base)
.map(o -> (Base) o)
.forEach(DominoUtil::recycle);
}
}
Finally the method that would do the job:
public class Example {
public static void yourEntryPoint() {
try {
// The last param is just a way to create an attachment from text
// You have InputStream to pass along obviously
addAttachment(doc, "Body", "fake1.txt", "this is fake text1");
addAttachment(doc, "Body", "fake2.txt", "this is fake text2");
addAttachment(doc, "Body", "fake3.txt", "this is fake text3");
removeAttachment(doc, "Body", "fake2.txt");
removeAttachment(doc, "Body", "fake3.txt");
} catch (NotesException e) {
throw new RuntimeException(e);
}
}
private static void addAttachment(Document doc, String itemName, String fileName, String data)
throws NotesException {
MIMEEntity mimeEntity = null;
Stream stm = null;
try {
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
MIMEEntity attachmentEntity = null;
if (optAttEntity.isPresent()) {
attachmentEntity = optAttEntity.get();
} else {
attachmentEntity = mimeEntity.createChildEntity();
MIMEHeader header = attachmentEntity.createHeader("Content-Disposition");
header.setHeaderValAndParams("attachment; filename="" + fileName + """);
}
stm = doc.getParentDatabase().getParent().createStream();
stm.writeText(data);
attachmentEntity.setContentFromBytes(stm,
"application/octet-stream",
MIMEEntity.ENC_IDENTITY_BINARY);
stm.close();
doc.closeMIMEEntities(true, itemName);
} finally {
DominoUtil.recycle(stm);
DominoUtil.recycle(mimeEntity);
}
}
private static void removeAttachment(Document doc, String itemName, String fileName)
throws NotesException {
MIMEEntity mimeEntity = null;
try {
// Get MIME entity
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
if (!optAttEntity.isPresent()) {
return;
}
optAttEntity.get().remove();
// Header cleaning on empty entity
if (mimeEntity.getFirstChildEntity() != null) {
doc.closeMIMEEntities(true, itemName);
} else {
mimeEntity.remove();
}
} finally {
DominoUtil.recycle(mimeEntity);
}
}
private static Optional<MIMEEntity> getAttachmentMimeEntity(MIMEEntity root, String fileName)
throws NotesException {
return DominoUtil
.getMimeEntitiesByContentType(root, MimeContentType.ATTACHMENT)
.stream()
.filter((ThrowablePredicate<MIMEEntity>) mime -> {
Optional<String> opt = DominoUtil.getMimeEntityAttachmentFilename(mime);
return opt.isPresent() && opt.get().equals(fileName);
})
.findFirst();
}
}
thanks, that could be helpful but your code is not complete public static Map<MimeContentType, List<MIMEEntity>> getMimeEntities(MIMEEntity entity, MimeContentType... contentTypes)
– Thomas Adrian
Nov 22 '18 at 16:49
Sorry, I don’t understand what you mean by that. I put the code together by stripping all the rest of the code out but what remained seems complete to me. Am I blind?
– shillem
Nov 22 '18 at 17:07
I get compile errors.
– Thomas Adrian
Nov 22 '18 at 17:12
Ok, for sure I left out the import statements. What are the errors? Do you use iava8 or 6?
– shillem
Nov 22 '18 at 17:14
No, look at the method signature i showed in the comment. I am using DDE10
– Thomas Adrian
Nov 22 '18 at 17:27
|
show 4 more comments
If you work with MIME methods to attach the file why not work with MIME methods to remove it as well?
I use my own framework so the following code might give you the impression to overcomplicate things but hopefully you should get the gist of it:
I have an enum that helps me navigate through the various MIME types. In this case you are dealing with ATTACHMENT
:
public enum MimeContentType {
ATTACHMENT("attachment") {
@Override
public boolean matches(String headers) {
int score = 0;
for (String header : headers) {
if (header.startsWith("Content-Disposition")) {
score++;
}
if (header.contains("attachment")) {
score++;
}
if (header.contains("filename")) {
score++;
}
if (score == 3) {
return true;
}
}
return false;
}
},
TEXT("text"),
TEXT_HTML("text/html"),
TEXT_PLAIN("text/plain");
private final String type;
private MimeContentType(String type) {
this.type = type;
}
public boolean matches(String headers) {
for (String header : headers) {
if (header.startsWith("Content-Type") && header.contains(type)) {
return true;
}
}
return false;
}
}
Then some helper classes:
@FunctionalInterface
public interface ThrowableConsumer<T> extends Consumer<T> {
@Override
default void accept(final T t) {
try {
acceptOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
void acceptOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableFunction<T, R> extends Function<T, R> {
@Override
default R apply(T t) {
try {
return applyOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
R applyOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowablePredicate<T> extends Predicate<T> {
@Override
default boolean test(T t) {
try {
return testOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
boolean testOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableSupplier<T> extends Supplier<T> {
@Override
default T get() {
try {
return getOrThrow();
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
T getOrThrow() throws Throwable;
}
public enum DominoUtil {
;
private static final Vector<String> MIME_FILTERED_HEADERS = new Vector<>();
static {
MIME_FILTERED_HEADERS.add("Content-Type");
MIME_FILTERED_HEADERS.add("Content-Disposition");
}
public static List<MIMEEntity> getMimeEntitiesByContentType(MIMEEntity entity,
MimeContentType contentType) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(contentType, "Content type cannot be null");
List<MIMEEntity> subentities = new ArrayList<>();
MIMEEntity nextEntity = null;
try {
nextEntity = entity.getNextEntity();
while (nextEntity != null) {
String entityFilteredHeaders = nextEntity
.getSomeHeaders(MIME_FILTERED_HEADERS, true)
.split("\n");
if (contentType.matches(entityFilteredHeaders)) {
subentities.add(nextEntity);
}
nextEntity = nextEntity.getNextEntity();
}
} finally {
DominoUtil.recycle(nextEntity);
}
return subentities;
}
public final static MIMEEntity getMimeEntity(Document doc, String itemName,
boolean createOnFail) throws NotesException {
if (itemName == null) {
throw new NullPointerException("Invalid MIME entity item name");
}
MIMEEntity mimeEntity = doc.getMIMEEntity(itemName);
if (mimeEntity == null) {
if (doc.hasItem(itemName)) {
doc.removeItem(itemName);
}
if (createOnFail) {
mimeEntity = doc.createMIMEEntity(itemName);
}
}
return mimeEntity;
}
public static Optional<String> getMimeEntityAttachmentFilename(MIMEEntity entity) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
return getMimeEntityHeaderValAndParams(
entity, (ThrowablePredicate<MIMEHeader>) h -> h.getHeaderVal().equals("attachment"))
.map(s -> {
Matcher m = Pattern.compile("filename=['"]?([^'"\s]+)").matcher(s);
m.find();
return m.group(1);
});
}
public static Optional<String> getMimeEntityHeaderValAndParams(
MIMEEntity entity, Predicate<MIMEHeader> matcher) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(matcher, "Matcher cannot be null");
Vector<?> headers = entity.getHeaderObjects();
try {
return headers
.stream()
.map(MIMEHeader.class::cast)
.filter(matcher)
.map((ThrowableFunction<MIMEHeader, String>) MIMEHeader::getHeaderValAndParams)
.findFirst();
} finally {
recycle(headers);
}
}
public static void recycle(Base... bases) {
for (Base base : bases) {
if (base != null) {
try {
base.recycle();
} catch (Exception e) {
// Do nothing
}
}
}
}
public static void recycle(Collection<? extends Object> objs) {
objs.stream()
.filter(o -> o instanceof Base)
.map(o -> (Base) o)
.forEach(DominoUtil::recycle);
}
}
Finally the method that would do the job:
public class Example {
public static void yourEntryPoint() {
try {
// The last param is just a way to create an attachment from text
// You have InputStream to pass along obviously
addAttachment(doc, "Body", "fake1.txt", "this is fake text1");
addAttachment(doc, "Body", "fake2.txt", "this is fake text2");
addAttachment(doc, "Body", "fake3.txt", "this is fake text3");
removeAttachment(doc, "Body", "fake2.txt");
removeAttachment(doc, "Body", "fake3.txt");
} catch (NotesException e) {
throw new RuntimeException(e);
}
}
private static void addAttachment(Document doc, String itemName, String fileName, String data)
throws NotesException {
MIMEEntity mimeEntity = null;
Stream stm = null;
try {
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
MIMEEntity attachmentEntity = null;
if (optAttEntity.isPresent()) {
attachmentEntity = optAttEntity.get();
} else {
attachmentEntity = mimeEntity.createChildEntity();
MIMEHeader header = attachmentEntity.createHeader("Content-Disposition");
header.setHeaderValAndParams("attachment; filename="" + fileName + """);
}
stm = doc.getParentDatabase().getParent().createStream();
stm.writeText(data);
attachmentEntity.setContentFromBytes(stm,
"application/octet-stream",
MIMEEntity.ENC_IDENTITY_BINARY);
stm.close();
doc.closeMIMEEntities(true, itemName);
} finally {
DominoUtil.recycle(stm);
DominoUtil.recycle(mimeEntity);
}
}
private static void removeAttachment(Document doc, String itemName, String fileName)
throws NotesException {
MIMEEntity mimeEntity = null;
try {
// Get MIME entity
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
if (!optAttEntity.isPresent()) {
return;
}
optAttEntity.get().remove();
// Header cleaning on empty entity
if (mimeEntity.getFirstChildEntity() != null) {
doc.closeMIMEEntities(true, itemName);
} else {
mimeEntity.remove();
}
} finally {
DominoUtil.recycle(mimeEntity);
}
}
private static Optional<MIMEEntity> getAttachmentMimeEntity(MIMEEntity root, String fileName)
throws NotesException {
return DominoUtil
.getMimeEntitiesByContentType(root, MimeContentType.ATTACHMENT)
.stream()
.filter((ThrowablePredicate<MIMEEntity>) mime -> {
Optional<String> opt = DominoUtil.getMimeEntityAttachmentFilename(mime);
return opt.isPresent() && opt.get().equals(fileName);
})
.findFirst();
}
}
thanks, that could be helpful but your code is not complete public static Map<MimeContentType, List<MIMEEntity>> getMimeEntities(MIMEEntity entity, MimeContentType... contentTypes)
– Thomas Adrian
Nov 22 '18 at 16:49
Sorry, I don’t understand what you mean by that. I put the code together by stripping all the rest of the code out but what remained seems complete to me. Am I blind?
– shillem
Nov 22 '18 at 17:07
I get compile errors.
– Thomas Adrian
Nov 22 '18 at 17:12
Ok, for sure I left out the import statements. What are the errors? Do you use iava8 or 6?
– shillem
Nov 22 '18 at 17:14
No, look at the method signature i showed in the comment. I am using DDE10
– Thomas Adrian
Nov 22 '18 at 17:27
|
show 4 more comments
If you work with MIME methods to attach the file why not work with MIME methods to remove it as well?
I use my own framework so the following code might give you the impression to overcomplicate things but hopefully you should get the gist of it:
I have an enum that helps me navigate through the various MIME types. In this case you are dealing with ATTACHMENT
:
public enum MimeContentType {
ATTACHMENT("attachment") {
@Override
public boolean matches(String headers) {
int score = 0;
for (String header : headers) {
if (header.startsWith("Content-Disposition")) {
score++;
}
if (header.contains("attachment")) {
score++;
}
if (header.contains("filename")) {
score++;
}
if (score == 3) {
return true;
}
}
return false;
}
},
TEXT("text"),
TEXT_HTML("text/html"),
TEXT_PLAIN("text/plain");
private final String type;
private MimeContentType(String type) {
this.type = type;
}
public boolean matches(String headers) {
for (String header : headers) {
if (header.startsWith("Content-Type") && header.contains(type)) {
return true;
}
}
return false;
}
}
Then some helper classes:
@FunctionalInterface
public interface ThrowableConsumer<T> extends Consumer<T> {
@Override
default void accept(final T t) {
try {
acceptOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
void acceptOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableFunction<T, R> extends Function<T, R> {
@Override
default R apply(T t) {
try {
return applyOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
R applyOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowablePredicate<T> extends Predicate<T> {
@Override
default boolean test(T t) {
try {
return testOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
boolean testOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableSupplier<T> extends Supplier<T> {
@Override
default T get() {
try {
return getOrThrow();
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
T getOrThrow() throws Throwable;
}
public enum DominoUtil {
;
private static final Vector<String> MIME_FILTERED_HEADERS = new Vector<>();
static {
MIME_FILTERED_HEADERS.add("Content-Type");
MIME_FILTERED_HEADERS.add("Content-Disposition");
}
public static List<MIMEEntity> getMimeEntitiesByContentType(MIMEEntity entity,
MimeContentType contentType) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(contentType, "Content type cannot be null");
List<MIMEEntity> subentities = new ArrayList<>();
MIMEEntity nextEntity = null;
try {
nextEntity = entity.getNextEntity();
while (nextEntity != null) {
String entityFilteredHeaders = nextEntity
.getSomeHeaders(MIME_FILTERED_HEADERS, true)
.split("\n");
if (contentType.matches(entityFilteredHeaders)) {
subentities.add(nextEntity);
}
nextEntity = nextEntity.getNextEntity();
}
} finally {
DominoUtil.recycle(nextEntity);
}
return subentities;
}
public final static MIMEEntity getMimeEntity(Document doc, String itemName,
boolean createOnFail) throws NotesException {
if (itemName == null) {
throw new NullPointerException("Invalid MIME entity item name");
}
MIMEEntity mimeEntity = doc.getMIMEEntity(itemName);
if (mimeEntity == null) {
if (doc.hasItem(itemName)) {
doc.removeItem(itemName);
}
if (createOnFail) {
mimeEntity = doc.createMIMEEntity(itemName);
}
}
return mimeEntity;
}
public static Optional<String> getMimeEntityAttachmentFilename(MIMEEntity entity) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
return getMimeEntityHeaderValAndParams(
entity, (ThrowablePredicate<MIMEHeader>) h -> h.getHeaderVal().equals("attachment"))
.map(s -> {
Matcher m = Pattern.compile("filename=['"]?([^'"\s]+)").matcher(s);
m.find();
return m.group(1);
});
}
public static Optional<String> getMimeEntityHeaderValAndParams(
MIMEEntity entity, Predicate<MIMEHeader> matcher) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(matcher, "Matcher cannot be null");
Vector<?> headers = entity.getHeaderObjects();
try {
return headers
.stream()
.map(MIMEHeader.class::cast)
.filter(matcher)
.map((ThrowableFunction<MIMEHeader, String>) MIMEHeader::getHeaderValAndParams)
.findFirst();
} finally {
recycle(headers);
}
}
public static void recycle(Base... bases) {
for (Base base : bases) {
if (base != null) {
try {
base.recycle();
} catch (Exception e) {
// Do nothing
}
}
}
}
public static void recycle(Collection<? extends Object> objs) {
objs.stream()
.filter(o -> o instanceof Base)
.map(o -> (Base) o)
.forEach(DominoUtil::recycle);
}
}
Finally the method that would do the job:
public class Example {
public static void yourEntryPoint() {
try {
// The last param is just a way to create an attachment from text
// You have InputStream to pass along obviously
addAttachment(doc, "Body", "fake1.txt", "this is fake text1");
addAttachment(doc, "Body", "fake2.txt", "this is fake text2");
addAttachment(doc, "Body", "fake3.txt", "this is fake text3");
removeAttachment(doc, "Body", "fake2.txt");
removeAttachment(doc, "Body", "fake3.txt");
} catch (NotesException e) {
throw new RuntimeException(e);
}
}
private static void addAttachment(Document doc, String itemName, String fileName, String data)
throws NotesException {
MIMEEntity mimeEntity = null;
Stream stm = null;
try {
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
MIMEEntity attachmentEntity = null;
if (optAttEntity.isPresent()) {
attachmentEntity = optAttEntity.get();
} else {
attachmentEntity = mimeEntity.createChildEntity();
MIMEHeader header = attachmentEntity.createHeader("Content-Disposition");
header.setHeaderValAndParams("attachment; filename="" + fileName + """);
}
stm = doc.getParentDatabase().getParent().createStream();
stm.writeText(data);
attachmentEntity.setContentFromBytes(stm,
"application/octet-stream",
MIMEEntity.ENC_IDENTITY_BINARY);
stm.close();
doc.closeMIMEEntities(true, itemName);
} finally {
DominoUtil.recycle(stm);
DominoUtil.recycle(mimeEntity);
}
}
private static void removeAttachment(Document doc, String itemName, String fileName)
throws NotesException {
MIMEEntity mimeEntity = null;
try {
// Get MIME entity
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
if (!optAttEntity.isPresent()) {
return;
}
optAttEntity.get().remove();
// Header cleaning on empty entity
if (mimeEntity.getFirstChildEntity() != null) {
doc.closeMIMEEntities(true, itemName);
} else {
mimeEntity.remove();
}
} finally {
DominoUtil.recycle(mimeEntity);
}
}
private static Optional<MIMEEntity> getAttachmentMimeEntity(MIMEEntity root, String fileName)
throws NotesException {
return DominoUtil
.getMimeEntitiesByContentType(root, MimeContentType.ATTACHMENT)
.stream()
.filter((ThrowablePredicate<MIMEEntity>) mime -> {
Optional<String> opt = DominoUtil.getMimeEntityAttachmentFilename(mime);
return opt.isPresent() && opt.get().equals(fileName);
})
.findFirst();
}
}
If you work with MIME methods to attach the file why not work with MIME methods to remove it as well?
I use my own framework so the following code might give you the impression to overcomplicate things but hopefully you should get the gist of it:
I have an enum that helps me navigate through the various MIME types. In this case you are dealing with ATTACHMENT
:
public enum MimeContentType {
ATTACHMENT("attachment") {
@Override
public boolean matches(String headers) {
int score = 0;
for (String header : headers) {
if (header.startsWith("Content-Disposition")) {
score++;
}
if (header.contains("attachment")) {
score++;
}
if (header.contains("filename")) {
score++;
}
if (score == 3) {
return true;
}
}
return false;
}
},
TEXT("text"),
TEXT_HTML("text/html"),
TEXT_PLAIN("text/plain");
private final String type;
private MimeContentType(String type) {
this.type = type;
}
public boolean matches(String headers) {
for (String header : headers) {
if (header.startsWith("Content-Type") && header.contains(type)) {
return true;
}
}
return false;
}
}
Then some helper classes:
@FunctionalInterface
public interface ThrowableConsumer<T> extends Consumer<T> {
@Override
default void accept(final T t) {
try {
acceptOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
void acceptOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableFunction<T, R> extends Function<T, R> {
@Override
default R apply(T t) {
try {
return applyOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
R applyOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowablePredicate<T> extends Predicate<T> {
@Override
default boolean test(T t) {
try {
return testOrThrow(t);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
boolean testOrThrow(T t) throws Throwable;
}
@FunctionalInterface
public interface ThrowableSupplier<T> extends Supplier<T> {
@Override
default T get() {
try {
return getOrThrow();
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
T getOrThrow() throws Throwable;
}
public enum DominoUtil {
;
private static final Vector<String> MIME_FILTERED_HEADERS = new Vector<>();
static {
MIME_FILTERED_HEADERS.add("Content-Type");
MIME_FILTERED_HEADERS.add("Content-Disposition");
}
public static List<MIMEEntity> getMimeEntitiesByContentType(MIMEEntity entity,
MimeContentType contentType) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(contentType, "Content type cannot be null");
List<MIMEEntity> subentities = new ArrayList<>();
MIMEEntity nextEntity = null;
try {
nextEntity = entity.getNextEntity();
while (nextEntity != null) {
String entityFilteredHeaders = nextEntity
.getSomeHeaders(MIME_FILTERED_HEADERS, true)
.split("\n");
if (contentType.matches(entityFilteredHeaders)) {
subentities.add(nextEntity);
}
nextEntity = nextEntity.getNextEntity();
}
} finally {
DominoUtil.recycle(nextEntity);
}
return subentities;
}
public final static MIMEEntity getMimeEntity(Document doc, String itemName,
boolean createOnFail) throws NotesException {
if (itemName == null) {
throw new NullPointerException("Invalid MIME entity item name");
}
MIMEEntity mimeEntity = doc.getMIMEEntity(itemName);
if (mimeEntity == null) {
if (doc.hasItem(itemName)) {
doc.removeItem(itemName);
}
if (createOnFail) {
mimeEntity = doc.createMIMEEntity(itemName);
}
}
return mimeEntity;
}
public static Optional<String> getMimeEntityAttachmentFilename(MIMEEntity entity) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
return getMimeEntityHeaderValAndParams(
entity, (ThrowablePredicate<MIMEHeader>) h -> h.getHeaderVal().equals("attachment"))
.map(s -> {
Matcher m = Pattern.compile("filename=['"]?([^'"\s]+)").matcher(s);
m.find();
return m.group(1);
});
}
public static Optional<String> getMimeEntityHeaderValAndParams(
MIMEEntity entity, Predicate<MIMEHeader> matcher) throws NotesException {
Objects.requireNonNull(entity, "Entity cannot be null");
Objects.requireNonNull(matcher, "Matcher cannot be null");
Vector<?> headers = entity.getHeaderObjects();
try {
return headers
.stream()
.map(MIMEHeader.class::cast)
.filter(matcher)
.map((ThrowableFunction<MIMEHeader, String>) MIMEHeader::getHeaderValAndParams)
.findFirst();
} finally {
recycle(headers);
}
}
public static void recycle(Base... bases) {
for (Base base : bases) {
if (base != null) {
try {
base.recycle();
} catch (Exception e) {
// Do nothing
}
}
}
}
public static void recycle(Collection<? extends Object> objs) {
objs.stream()
.filter(o -> o instanceof Base)
.map(o -> (Base) o)
.forEach(DominoUtil::recycle);
}
}
Finally the method that would do the job:
public class Example {
public static void yourEntryPoint() {
try {
// The last param is just a way to create an attachment from text
// You have InputStream to pass along obviously
addAttachment(doc, "Body", "fake1.txt", "this is fake text1");
addAttachment(doc, "Body", "fake2.txt", "this is fake text2");
addAttachment(doc, "Body", "fake3.txt", "this is fake text3");
removeAttachment(doc, "Body", "fake2.txt");
removeAttachment(doc, "Body", "fake3.txt");
} catch (NotesException e) {
throw new RuntimeException(e);
}
}
private static void addAttachment(Document doc, String itemName, String fileName, String data)
throws NotesException {
MIMEEntity mimeEntity = null;
Stream stm = null;
try {
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
MIMEEntity attachmentEntity = null;
if (optAttEntity.isPresent()) {
attachmentEntity = optAttEntity.get();
} else {
attachmentEntity = mimeEntity.createChildEntity();
MIMEHeader header = attachmentEntity.createHeader("Content-Disposition");
header.setHeaderValAndParams("attachment; filename="" + fileName + """);
}
stm = doc.getParentDatabase().getParent().createStream();
stm.writeText(data);
attachmentEntity.setContentFromBytes(stm,
"application/octet-stream",
MIMEEntity.ENC_IDENTITY_BINARY);
stm.close();
doc.closeMIMEEntities(true, itemName);
} finally {
DominoUtil.recycle(stm);
DominoUtil.recycle(mimeEntity);
}
}
private static void removeAttachment(Document doc, String itemName, String fileName)
throws NotesException {
MIMEEntity mimeEntity = null;
try {
// Get MIME entity
mimeEntity = DominoUtil.getMimeEntity(doc, itemName, true);
Optional<MIMEEntity> optAttEntity = getAttachmentMimeEntity(mimeEntity, fileName);
if (!optAttEntity.isPresent()) {
return;
}
optAttEntity.get().remove();
// Header cleaning on empty entity
if (mimeEntity.getFirstChildEntity() != null) {
doc.closeMIMEEntities(true, itemName);
} else {
mimeEntity.remove();
}
} finally {
DominoUtil.recycle(mimeEntity);
}
}
private static Optional<MIMEEntity> getAttachmentMimeEntity(MIMEEntity root, String fileName)
throws NotesException {
return DominoUtil
.getMimeEntitiesByContentType(root, MimeContentType.ATTACHMENT)
.stream()
.filter((ThrowablePredicate<MIMEEntity>) mime -> {
Optional<String> opt = DominoUtil.getMimeEntityAttachmentFilename(mime);
return opt.isPresent() && opt.get().equals(fileName);
})
.findFirst();
}
}
edited Nov 23 '18 at 15:43
answered Nov 22 '18 at 13:48
shillemshillem
1,195611
1,195611
thanks, that could be helpful but your code is not complete public static Map<MimeContentType, List<MIMEEntity>> getMimeEntities(MIMEEntity entity, MimeContentType... contentTypes)
– Thomas Adrian
Nov 22 '18 at 16:49
Sorry, I don’t understand what you mean by that. I put the code together by stripping all the rest of the code out but what remained seems complete to me. Am I blind?
– shillem
Nov 22 '18 at 17:07
I get compile errors.
– Thomas Adrian
Nov 22 '18 at 17:12
Ok, for sure I left out the import statements. What are the errors? Do you use iava8 or 6?
– shillem
Nov 22 '18 at 17:14
No, look at the method signature i showed in the comment. I am using DDE10
– Thomas Adrian
Nov 22 '18 at 17:27
|
show 4 more comments
thanks, that could be helpful but your code is not complete public static Map<MimeContentType, List<MIMEEntity>> getMimeEntities(MIMEEntity entity, MimeContentType... contentTypes)
– Thomas Adrian
Nov 22 '18 at 16:49
Sorry, I don’t understand what you mean by that. I put the code together by stripping all the rest of the code out but what remained seems complete to me. Am I blind?
– shillem
Nov 22 '18 at 17:07
I get compile errors.
– Thomas Adrian
Nov 22 '18 at 17:12
Ok, for sure I left out the import statements. What are the errors? Do you use iava8 or 6?
– shillem
Nov 22 '18 at 17:14
No, look at the method signature i showed in the comment. I am using DDE10
– Thomas Adrian
Nov 22 '18 at 17:27
thanks, that could be helpful but your code is not complete public static Map<MimeContentType, List<MIMEEntity>> getMimeEntities(MIMEEntity entity, MimeContentType... contentTypes)
– Thomas Adrian
Nov 22 '18 at 16:49
thanks, that could be helpful but your code is not complete public static Map<MimeContentType, List<MIMEEntity>> getMimeEntities(MIMEEntity entity, MimeContentType... contentTypes)
– Thomas Adrian
Nov 22 '18 at 16:49
Sorry, I don’t understand what you mean by that. I put the code together by stripping all the rest of the code out but what remained seems complete to me. Am I blind?
– shillem
Nov 22 '18 at 17:07
Sorry, I don’t understand what you mean by that. I put the code together by stripping all the rest of the code out but what remained seems complete to me. Am I blind?
– shillem
Nov 22 '18 at 17:07
I get compile errors.
– Thomas Adrian
Nov 22 '18 at 17:12
I get compile errors.
– Thomas Adrian
Nov 22 '18 at 17:12
Ok, for sure I left out the import statements. What are the errors? Do you use iava8 or 6?
– shillem
Nov 22 '18 at 17:14
Ok, for sure I left out the import statements. What are the errors? Do you use iava8 or 6?
– shillem
Nov 22 '18 at 17:14
No, look at the method signature i showed in the comment. I am using DDE10
– Thomas Adrian
Nov 22 '18 at 17:27
No, look at the method signature i showed in the comment. I am using DDE10
– Thomas Adrian
Nov 22 '18 at 17:27
|
show 4 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53431447%2fhow-to-add-and-remove-mime-attachments-correctly%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown