Skip to content
Snippets Groups Projects
Commit 8cafb8c3 authored by Bunyamin Aslan's avatar Bunyamin Aslan
Browse files

It works ! A mail sender and a mail retriever is implemented to see how the program works

parent c647acb3
No related branches found
No related tags found
No related merge requests found
.env 0 → 100644
#MANDATORY VARIABLES
# Server settings
#Port where the server will be listening
SERVER_PORT=8025
#Hostname of the server
SERVER_HOSTNAME=localhost
#How many thread are always running in the server (even if no client to handle)
#CONNECTION_CORE=0
#Max connection that can handle the server at the same time
CONNECTION_MAX=1024
#Seconds that have the client to send the mail
IDLE_TIMEOUT=5
# DB settings
#MongoDb host IP
DB_HOST=127.0.0.1
#MongoDb Port (generally 27017 if localhost)
DB_PORT=27017
#MongoDb database name to use
DB_NAME=mydb
#MongoDb collection name to use (to store mails)
COLLECTION_NAME=mail_collection
#MongoDb bucket name to use (to store files)
BUCKET_NAME=attachments
/target/
/attachments/retrieving/doc.odt
File added
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<!--
Checkstyle configuration based on sun_checks.xml with:
- magic number check is disabled
- hidden field is disabled
- JavadocPackage is disabled
- variables naming is "^[a-z][a-z0-9\_]*$"
Checkstyle configuration that checks the sun coding conventions from:
- the Java Language Specification at
http://java.sun.com/docs/books/jls/second_edition/html/index.html
- the Sun Code Conventions at http://java.sun.com/docs/codeconv/
- the Javadoc guidelines at
http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
- the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html
- some best practices
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net (or in your downloaded distribution).
Most Checks are configurable, be sure to consult the documentation.
To completely disable a check, just comment it out or delete it from the file.
Finally, it is worth reading the documentation.
-->
<module name="Checker">
<!--
If you set the basedir property below, then all reported file
names will be relative to the specified directory. See
http://checkstyle.sourceforge.net/5.x/config.html#Checker
<property name="basedir" value="${basedir}"/>
-->
<!-- Checks that each Java package has a Javadoc file used for commenting. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage -->
<!-- <module name="JavadocPackage">
<property name="allowLegacy" value="true"/>
</module>-->
<!-- Checks whether files end with a new line. -->
<!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
<module name="NewlineAtEndOfFile"/>
<!-- Checks that property files contain the same keys. -->
<!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
<module name="Translation"/>
<module name="FileLength"/>
<!-- Following interprets the header file as regular expressions. -->
<!-- <module name="RegexpHeader"/> -->
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="RegexpSingleline">
<!-- \s matches whitespace character, $ matches end of line. -->
<property name="format" value="\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<module name="TreeWalker">
<property name="cacheFile" value="target/checkstyle_cache"/>
<!-- required for SuppressWarningsFilter (and other Suppress* rules not used here) -->
<!-- see http://checkstyle.sourceforge.net/config_annotation.html#SuppressWarningsHolder -->
<module name="SuppressWarningsHolder"/>
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="public"/>
<property name="allowMissingReturnTag" value="true" />
<property name="allowMissingParamTags" value="true" />
</module>
<module name="JavadocType"/>
<module name="JavadocVariable">
<property name="scope" value="public"/>
</module>
<module name="JavadocStyle"/>
<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module name="ConstantName"/>
<module name="LocalFinalVariableName">
<property name="format" value="^[a-z][a-z0-9\_]*$"/>
</module>
<module name="LocalVariableName">
<property name="format" value="^[a-z][a-z0-9\_]*$"/>
<property name="allowOneCharVarInForLoop" value="true"/>
</module>
<module name="MemberName">
<property name="format" value="^[a-z][a-z0-9\_]*$"/>
</module>
<module name="ParameterName">
<property name="format" value="^[a-z][a-z0-9\_]*$"/>
</module>
<!--<module name="CatchParameterName">
<property name="format" value="^[a-z][a-z0-9\_]+$"/>
</module>-->
<module name="StaticVariableName">
<property name="format" value="^[a-z][a-z0-9\_]*$"/>
</module>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="TypeName"/>
<!-- Checks for Headers -->
<!-- See http://checkstyle.sf.net/config_header.html -->
<!-- <module name="Header"> -->
<!-- The follow property value demonstrates the ability -->
<!-- to have access to ANT properties. In this case it uses -->
<!-- the ${basedir} property to allow Checkstyle to be run -->
<!-- from any directory within a project. See property -->
<!-- expansion, -->
<!-- http://checkstyle.sf.net/config.html#properties -->
<!-- <property -->
<!-- name="headerFile" -->
<!-- value="${basedir}/java.header"/> -->
<!-- </module> -->
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<!--<module name="AvoidStarImport"/>-->
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="LineLength"/>
<module name="MethodLength"/>
<!--<module name="ParameterNumber"/>-->
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="EmptyForIteratorPad"/>
<module name="MethodParamPad"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<module name="AvoidInlineConditionals"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<!-- <module name="HiddenField"/> -->
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<!-- <module name="MagicNumber"/> -->
<module name="MissingSwitchDefault"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<!--<module name="DesignForExtension"/>-->
<!--<module name="FinalClass"/>-->
<module name="HideUtilityClassConstructor"/>
<!--<module name="InterfaceIsType"/>-->
<module name="VisibilityModifier"/>
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="ArrayTypeStyle"/>
<module name="FinalParameters"/>
<module name="TodoComment"/>
<module name="UpperEll"/>
</module>
<!-- Support @SuppressWarnings (added in Checkstyle 5.7) -->
<!-- see http://checkstyle.sourceforge.net/config.html#SuppressWarningsFilter -->
<module name="SuppressWarningsFilter"/>
<!-- Checks properties file for a duplicated properties. -->
<!-- See http://checkstyle.sourceforge.net/config_misc.html#UniqueProperties -->
<module name="UniqueProperties"/>
</module>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="debug" additivity="false">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
pom.xml 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>mongo-mail-example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
<dependency>
<groupId>be.cylab</groupId>
<artifactId>mongo-mail</artifactId>
<version>0.0.2</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>3.9.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.16</version>
<executions>
<execution>
<id>validate</id>
<phase>verify</phase>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<linkXRef>false</linkXRef>
</configuration>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package be.cylab.mongomailexample;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author bunyamin
*/
public class Attachment {
private final String filename;
private final DataSource datasource;
/**
* constructor.
*
* @param file_path obj.
*/
public Attachment(String file_path) {
this.filename = parsePath(file_path);
this.datasource = new FileDataSource(file_path);
}
/**
* parse path.
*
* @param path obj.
* @return filename.
*/
private String parsePath(String path) {
String[] s = path.split("/");
return s[s.length - 1];
}
/**
* get data source.
*
* @return data source.
*/
public DataSource getDatasource() {
return datasource;
}
/**
* getter.
*
* @return filename.
*/
public String getFilename() {
return filename;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package be.cylab.mongomailexample;
import com.mongodb.MongoClientSettings;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import org.bson.Document;
import org.bson.types.ObjectId;
/**
*
* @author bunyamin
*/
public class MailRetriever {
private final MongoClient mongo_client; //This is thread safe
private final MongoDatabase mongo_database;
private final MongoCollection mongo_collection;
private final GridFSBucket bucket;
public MailRetriever() {
int db_port = 27017;
String db_host = "127.0.0.1";
String db_name = "mydb";
String collection_name = "mail_collection";
String bucket_name = "attachments";
this.mongo_client = MongoClients.create(
MongoClientSettings.builder().applyToClusterSettings(builder
-> builder.hosts(Arrays.asList(
new ServerAddress(db_host, db_port)))).build());
this.bucket = GridFSBuckets.create(
this.mongo_client.getDatabase(db_name), bucket_name);
this.mongo_database = mongo_client.getDatabase(db_name);
this.mongo_collection = mongo_client.getDatabase(db_name).
getCollection(collection_name);
}
/**
* We retrieve only the mail sent to alice and smith.
*
* @return the mail sent to alice and smith in bson format.
*/
public Document retrieveMail() {
Document doc = (Document) mongo_collection.
find(new Document("TO", "smith@gmail.com")).first();
return doc;
}
/**
* download doc.odt attachment in attachments/retrieving/ folder.
*
* @param mail
* @throws FileNotFoundException
* @throws IOException
*/
public void downloadAttachment(Document mail)
throws FileNotFoundException, IOException {
ArrayList<Document> body = (ArrayList<Document>) mail.get("BODY");
ObjectId fileid = (ObjectId) body.get(1).get("FILE-ID");
try (FileOutputStream stream
= new FileOutputStream("attachments/retrieving/doc.odt")) {
bucket.downloadToStream(fileid, stream);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package be.cylab.mongomailexample;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
/**
*
* @author bunyamin
*/
public class MailSender {
private InternetAddress sender;
private ArrayList<InternetAddress> recipients;
private String content_message;
private ArrayList<Attachment> content_attachments;
private final Session session;
private String subject;
/**
* Constructor.
*/
public MailSender() {
this.recipients = new ArrayList<>();
this.content_attachments = new ArrayList<>();
Properties props = System.getProperties();
props.put("mail.smtp.host", "127.0.0.1");
props.put("mail.smtp.port", "8025");
this.session = Session.getInstance(props, null);
}
/**
* Set content message.
*
* @param content_message obj.
*/
public void setContent_message(String content_message) {
this.content_message = content_message;
}
/**
* set sender.
*
* @param sender obj.
*/
public void setSender(InternetAddress sender) {
this.sender = sender;
}
/**
* add attachment.
*
* @param att obj.
*/
public void addAttachment(Attachment att) {
this.content_attachments.add(att);
}
/**
* add recipient.
*
* @param recipient obj.
*/
public void addRecipient(InternetAddress recipient) {
this.recipients.add(recipient);
}
/**
* reset mail.
*/
public void resetMail() {
this.recipients = new ArrayList<>();
this.content_attachments = new ArrayList<>();
}
/**
* set subject.
*
* @param subj obj.
*/
public void setSubject(String subj) {
this.subject = subj;
}
/**
* send mail.
*
* @throws MessagingException
*/
public void sendMail() throws MessagingException {
MimeMessage mail = new MimeMessage(session);
mail.addHeader("Content-type", "text/plain; charset=UTF-8");
mail.addHeader("format", "flowed");
mail.addHeader("Content-Transfer-Encoding", "8bit");
mail.setText(content_message);
mail.setFrom(sender);
mail.setSubject(subject);
mail.setSentDate(new Date());
for (int i = 0; i < recipients.size(); i++) {
mail.addRecipient(Message.RecipientType.TO, recipients.get(i));
}
if (content_attachments.isEmpty()) {
Transport.send(mail);
return;
}
Multipart multipart = new MimeMultipart();
//If attachment, we don't must override our message by the multipart
MimeBodyPart mimebodypart = new MimeBodyPart();
mimebodypart.setText(content_message);
multipart.addBodyPart(mimebodypart);
for (int i = 0; i < content_attachments.size(); i++) {
Attachment att = content_attachments.get(i);
mimebodypart = new MimeBodyPart();
mimebodypart.setDataHandler(new DataHandler(att.getDatasource()));
mimebodypart.setFileName(att.getFilename());
multipart.addBodyPart(mimebodypart);
}
mail.setContent(multipart);
Transport.send(mail);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package be.cylab.mongomailexample;
import be.cylab.mongomail.server.Server;
import java.io.IOException;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.bson.Document;
/**
*
* @author bunyamin
*/
public class Main {
private Main() {
}
public static void main(String[] args)
throws AddressException, MessagingException, IOException {
Server.launchServer("./", "./");
MailSender mail_sender = new MailSender();
//Simple mail from bob to alice
mail_sender.setContent_message("This is the content of the "
+ "first message\n\nPS: post scriptum.");
mail_sender.setSubject("This is the subject of the mail number 1");
mail_sender.setSender(new InternetAddress("bob@gmail.com"));
mail_sender.addRecipient(new InternetAddress("alice@gmail.com"));
mail_sender.sendMail();
//Mail with attachemt from bob to alice and smith
mail_sender.resetMail();
mail_sender.setContent_message("This is the content of the "
+ "second message\n\nPS: post scriptum.");
mail_sender.setSubject("This is the subject of the mail number 2");
mail_sender.setSender(new InternetAddress("bob@gmail.com"));
mail_sender.addRecipient(new InternetAddress("alice@gmail.com"));
mail_sender.addRecipient(new InternetAddress("smith@gmail.com"));
mail_sender.addAttachment(new Attachment("attachments/doc.odt"));
mail_sender.sendMail();
//Retrieve the second mail, also download the attachment from mongodb
MailRetriever retriever = new MailRetriever();
Document mail2 = retriever.retrieveMail();
retriever.downloadAttachment(mail2);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment