Skip to content

Commit

Permalink
Multipart performs blocking call in every instantiation #699
Browse files Browse the repository at this point in the history
Signed-off-by: Jorge Bescos Gascon <[email protected]>
  • Loading branch information
jbescos committed Mar 4, 2024
1 parent aa1dc71 commit edae19d
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 26 deletions.
33 changes: 32 additions & 1 deletion api/src/main/java/jakarta/mail/Message.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -17,11 +17,13 @@
package jakarta.mail;

import jakarta.mail.search.SearchTerm;
import jakarta.mail.util.StreamProvider;

import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Date;
import java.util.ServiceConfigurationError;

/**
* This class models an email message. This is an abstract class.
Expand Down Expand Up @@ -705,4 +707,33 @@ protected void setExpunged(boolean expunged) {
public boolean match(SearchTerm term) throws MessagingException {
return term.match(this);
}

/**
* Obtains the {@link StreamProvider} from the session, if exists.
* Otherwise it obtains it from
* {@link Session#getDefaultInstance(java.util.Properties, Authenticator)}.
*
* @return the StreamProvider implementation from the session.
* @throws MessagingException if errors.
*
* @since JavaMail 2.2
*/
protected StreamProvider provider() throws MessagingException {
try {
try {
final Session s = this.session;
if (s != null) {
return s.getStreamProvider();
} else {
return Session.getDefaultInstance(System.getProperties(),
null).getStreamProvider();
}
} catch (ServiceConfigurationError sce) {
throw new IllegalStateException(sce);
}
} catch (RuntimeException re) {
throw new MessagingException("Unable to get "
+ StreamProvider.class.getName(), re);
}
}
}
32 changes: 29 additions & 3 deletions api/src/main/java/jakarta/mail/Multipart.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -21,6 +21,8 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Multipart is a container that holds multiple body parts. Multipart
Expand All @@ -42,6 +44,7 @@

public abstract class Multipart {

private static final Logger LOGGER = Logger.getLogger(Multipart.class.getName());
/**
* Vector of BodyPart objects.
*/
Expand All @@ -64,9 +67,9 @@ public abstract class Multipart {
/**
* Instance of stream provider.
*
* @since JavaMail 2.1
* @since JavaMail 2.2
*/
protected final StreamProvider streamProvider = StreamProvider.provider();
private volatile StreamProvider streamProvider;

/**
* Default constructor. An empty Multipart object is created.
Expand Down Expand Up @@ -266,4 +269,27 @@ public synchronized Part getParent() {
public synchronized void setParent(Part parent) {
this.parent = parent;
}

protected StreamProvider provider() {
if (streamProvider == null) {
synchronized (this) {
if (streamProvider == null) {
if (parent != null && parent instanceof Message) {
try {
streamProvider = ((Message)parent).provider();
} catch (MessagingException e) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Cannot reuse streamProvider", e);
}
}
}
}
if (streamProvider == null) {
streamProvider = StreamProvider.provider();
}
}
}
return streamProvider;
}

}
19 changes: 0 additions & 19 deletions api/src/main/java/jakarta/mail/internet/MimeMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -2322,23 +2322,4 @@ protected MimeMessage createMimeMessage(Session session)
throws MessagingException {
return new MimeMessage(session);
}

private StreamProvider provider() throws MessagingException {
try {
try {
final Session s = this.session;
if (s != null) {
return s.getStreamProvider();
} else {
return Session.getDefaultInstance(System.getProperties(),
null).getStreamProvider();
}
} catch (ServiceConfigurationError sce) {
throw new IllegalStateException(sce);
}
} catch (RuntimeException re) {
throw new MessagingException("Unable to get "
+ StreamProvider.class.getName(), re);
}
}
}
6 changes: 3 additions & 3 deletions api/src/main/java/jakarta/mail/internet/MimeMultipart.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -520,7 +520,7 @@ public synchronized void writeTo(OutputStream os)

String boundary = "--" +
(new ContentType(contentType)).getParameter("boundary");
LineOutputStream los = streamProvider.outputLineStream(os, false);
LineOutputStream los = provider().outputLineStream(os, false);
// if there's a preamble, write it out
if (preamble != null) {
byte[] pb = MimeUtility.getBytes(preamble);
Expand Down Expand Up @@ -601,7 +601,7 @@ protected synchronized void parse() throws MessagingException {

try {
// Skip and save the preamble
LineInputStream lin = streamProvider.inputLineStream(in, false);
LineInputStream lin = provider().inputLineStream(in, false);
StringBuilder preamblesb = null;
String line;
while ((line = lin.readLine()) != null) {
Expand Down

0 comments on commit edae19d

Please sign in to comment.