Skip to content

Commit

Permalink
implemented parser for emails
Browse files Browse the repository at this point in the history
  • Loading branch information
Yariki committed Feb 1, 2017
1 parent 09ce466 commit c831f50
Show file tree
Hide file tree
Showing 11 changed files with 379 additions and 0 deletions.
Binary file removed arch/emailparser.ldb
Binary file not shown.
12 changes: 12 additions & 0 deletions src/main/java/com/fruitfactory/controllers/OFEmailController.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.fruitfactory.controllers;

import com.fruitfactory.infrastructure.OFItemsReader;
import com.fruitfactory.interfaces.IOFItemsReader;
import com.fruitfactory.models.OFItemsContainer;
import com.fruitfactory.models.response.OFEmailResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
Expand All @@ -13,11 +16,20 @@
@RequestMapping(value = "/email")
public class OFEmailController {

private final IOFItemsReader reader = new OFItemsReader();

public OFEmailController() {
}

@RequestMapping(value = "/items",method = RequestMethod.POST)
public OFEmailResponse putEmailContainer(@RequestBody String body){
OFEmailResponse response = new OFEmailResponse(false,"");
try {
OFItemsContainer container = reader.parseContainer(body);




response.setStatus(true);
}catch(Exception ex){
response.setMessage(ex.getMessage());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.fruitfactory.infrastructure;

import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;

/**
* Created by Yariki on 2/1/2017.
*/
public class OFConversationIndexData {

private static final int RESERVED_INDEX = 0;
private static final int CONVERSSATION_INDEX_OFFSET = 6;
private static final int CONVERSATION_INDEX_GUID_LENGHT = 16;
private static final int CONVERSATION_INDEX_LEGHT = CONVERSSATION_INDEX_OFFSET + CONVERSATION_INDEX_GUID_LENGHT;
private static final int CONVERSATION_INDEX_STRING_LENGHT = CONVERSATION_INDEX_LEGHT * 2;
private static final int CONVERSATION_RESPONSE_LEVEL_LENGHT = 5;

private byte[] data;
private String hex_string;

public OFConversationIndexData(byte[] data) {
this.data = data;
init(this.data);
}

public byte getReservedValue() {
return data[RESERVED_INDEX];
}

public UUID getConversationUUID(String conversationTopic, boolean conversationIndexTracking) throws NoSuchAlgorithmException {
boolean useTopic = true;
UUID uuId = null;
//TODO: get raw id without any changes (according subject etc)
if (data != null && data.length >= CONVERSATION_INDEX_LEGHT && getReservedValue() == 0x01) {
byte[] uuidArray = getConversationIndexUuidArray();
uuId = UUID.nameUUIDFromBytes(uuidArray);
useTopic = false;
}
return uuId;
}

public boolean isDataEmpty(){
return data == null;
}

public byte[] getConversationIndexUuidArray() {
byte[] uuidArray = Arrays.copyOfRange(data, CONVERSSATION_INDEX_OFFSET,
CONVERSATION_INDEX_GUID_LENGHT);
return uuidArray;
}

public Date getConversationFileTime() {
Date date = null;
byte[] filetimeArr = Arrays.copyOfRange(data, 0, CONVERSSATION_INDEX_OFFSET);
String hex_str = javax.xml.bind.DatatypeConverter.printHexBinary(filetimeArr) + "0000";
long mil = Long.parseLong(hex_str, 16);
date = convertFILETIMEToDate(mil);
return date;
}

private static Date convertFILETIMEToDate(long filetime) {
// Filetime Epoch is JAN 01 1601
// java date Epoch is January 1, 1970
// so take the number and subtract java Epoch:
long javaTime = filetime - 0x19db1ded53e8000L;

// convert UNITS from (100 nano-seconds) to (milliseconds)
javaTime /= 10000;

// Date(long date)
// Allocates a Date object and initializes it to represent
// the specified number of milliseconds since the standard base
// time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
Date theDate = new Date(javaTime);

return theDate;
}

public String getHexString() {
return hex_string;
}

public int getConversationIndex() {
int difference = hex_string.length() - CONVERSATION_INDEX_STRING_LENGHT;
if (difference > 0) {
return (difference / (CONVERSATION_RESPONSE_LEVEL_LENGHT * 2)) + 1;
}
return 0;
}

public String getOutlookConversationId() {
if (hex_string.length() < CONVERSATION_INDEX_STRING_LENGHT) {
return "";
}
String temp = hex_string.substring(CONVERSSATION_INDEX_OFFSET * 2, CONVERSATION_INDEX_STRING_LENGHT);
return temp;
}

private void init(byte[] buffer) {
if (buffer == null || buffer.length == 0) {
return;
}
hex_string = javax.xml.bind.DatatypeConverter.printHexBinary(buffer);
}


}
103 changes: 103 additions & 0 deletions src/main/java/com/fruitfactory/infrastructure/OFDataParse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.fruitfactory.infrastructure;

import com.fasterxml.jackson.databind.deser.Deserializers;
import com.fruitfactory.infrastructure.core.OFDataProcess;
import com.fruitfactory.interfaces.IOFDataRepositoryPipe;
import com.fruitfactory.models.OFAttachment;
import com.fruitfactory.models.OFEmail;
import com.fruitfactory.models.OFItemsContainer;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import org.apache.tika.Tika;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.tika.metadata.Metadata;

/**
* Created by Yariki on 2/1/2017.
*/
public class OFDataParse extends OFDataProcess {

private final IOFDataRepositoryPipe dataTarget;

private final Tika tika = new Tika();

public OFDataParse(IOFDataRepositoryPipe dataSource, IOFDataRepositoryPipe dataTarget, String name) {
super(dataSource, name);
this.dataTarget = dataTarget;
}

@Override
protected void processData(OFItemsContainer container) {
try {
processEmail(container);
processAttachments(container);
dataTarget.pushData(container);
}catch (Exception ex){

}
}

private void processAttachments(OFItemsContainer container) {
if(container.getAttachments() == null || container.getAttachments().isEmpty()){
return;
}
try {
for(OFAttachment attachment : container.getAttachments()){
processAttachment(attachment);
}
}catch (Exception ex){

}
}

private void processAttachment(OFAttachment attachment) {
if(attachment.getContent() == null){
return;
}
try{
String parsedContent = "";
byte[] byteBuffer = Base64.decode(attachment.getContent());
parsedContent = tika.parseToString(new ByteInputStream(byteBuffer,byteBuffer.length), new Metadata());
attachment.setContent(parsedContent);
}catch (Exception ex){

}
}

private void processEmail(OFItemsContainer container){
if(container.getEmail() == null){
return;
}
OFEmail email = container.getEmail();
try {
OFConversationIndexData indexData = new OFConversationIndexData(email.getConversationindex().getBytes()) ;
email.setConversationindex(Integer.toString(indexData.getConversationIndex()));
email.setOutlookconversationid(indexData.getOutlookConversationId());
String body = null;
String htmlBody = null;
try {
body = new String(Base64.decode(email.getContent()));
}catch (Exception ex){

}
try {
htmlBody = new String(Base64.decode(email.getHtmlcontent()));
}catch(Exception ex){

}
String analyzedContent = null;

if(body != null && !body.isEmpty()){
byte[] bytes = body.getBytes();
analyzedContent = tika.parseToString(new ByteInputStream(bytes,bytes.length),new Metadata());
} else if(htmlBody != null && !htmlBody.isEmpty()){
byte[] bytes = htmlBody.getBytes();
analyzedContent = tika.parseToString(new ByteInputStream(bytes,bytes.length),new Metadata());
}
email.setAnalyzedcontent(analyzedContent);

}catch (Exception ex){

}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.fruitfactory.infrastructure;

import com.fruitfactory.interfaces.IOFDataRepositoryPipe;
import com.fruitfactory.models.OFItemsContainer;

import java.util.concurrent.LinkedBlockingQueue;

/**
* Created by Yariki on 1/29/2017.
*/
public class OFDateRepositoryPipe implements IOFDataRepositoryPipe {

private LinkedBlockingQueue<OFItemsContainer> dataContainer;
private final Object syncObject = new Object();
private volatile boolean available = false;

public OFDateRepositoryPipe() {
dataContainer = new LinkedBlockingQueue<>();
}

@Override
public synchronized void pushData(OFItemsContainer container) {
try{
dataContainer.put(container);
available = true;
syncObject.notifyAll();
}catch(InterruptedException ie){

}catch (Exception ex){

}
}

@Override
public synchronized void stopNotify() {
syncObject.notifyAll();
}

@Override
public synchronized OFItemsContainer popData() {
if(!available){
try {
syncObject.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
OFItemsContainer container = dataContainer.poll();
available = !dataContainer.isEmpty();
return container;
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/fruitfactory/infrastructure/OFItemsReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.fruitfactory.infrastructure;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.fruitfactory.interfaces.IOFItemsReader;
import com.fruitfactory.models.OFItemsContainer;

/**
* Created by Yariki on 1/29/2017.
*/
public class OFItemsReader implements IOFItemsReader {

public OFItemsReader() {

}

@Override
public OFItemsContainer parseContainer(String body) {
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").create();
OFItemsContainer container = gson.fromJson(body,OFItemsContainer.class);
return container;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.fruitfactory.infrastructure.core;

import com.fruitfactory.interfaces.IOFDataProcessThread;
import com.fruitfactory.interfaces.IOFDataRepositoryPipe;
import com.fruitfactory.models.OFItemsContainer;

/**
* Created by Yariki on 2/1/2017.
*/
public abstract class OFDataProcess extends Thread implements IOFDataProcessThread{

private final IOFDataRepositoryPipe dataSource;
private volatile boolean stop = false;

public OFDataProcess(IOFDataRepositoryPipe dataSource, String name) {
super(name);
this.dataSource = dataSource;
}

@Override
public synchronized void run() {
while (!stop){
OFItemsContainer container = null;
try {
container = dataSource.popData();
processData(container);
}catch(Exception ex){

}
}
}

protected abstract void processData(OFItemsContainer container);

@Override
public void close() {
dataSource.stopNotify();
stop = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.fruitfactory.interfaces;

/**
* Created by Yariki on 1/29/2017.
*/
public interface IOFDataProcessThread {

void start();

void close();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.fruitfactory.interfaces;

import com.fruitfactory.models.OFItemsContainer;

/**
* Created by Yariki on 1/29/2017.
*/
public interface IOFDataRepositoryPipe {

void pushData(OFItemsContainer container) throws InterruptedException;

OFItemsContainer popData();

void stopNotify();

}
Loading

0 comments on commit c831f50

Please sign in to comment.