Skip to content

Commit 32b0447

Browse files
author
Rustam Aliyev
committed
added filtering chain and sample filters
1 parent dd76ff2 commit 32b0447

File tree

6 files changed

+318
-2
lines changed

6 files changed

+318
-2
lines changed

modules/lmtp/src/main/java/com/elasticinbox/lmtp/delivery/ElasticInboxDeliveryAgent.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
import com.ecyrd.speed4j.StopWatch;
4242
import com.elasticinbox.lmtp.Activator;
43+
import com.elasticinbox.lmtp.filter.*;
4344
import com.elasticinbox.lmtp.server.api.DeliveryException;
4445
import com.elasticinbox.lmtp.server.api.DeliveryReturnCode;
4546
import com.elasticinbox.core.MessageDAO;
@@ -49,7 +50,6 @@
4950
import com.elasticinbox.core.message.id.MessageIdBuilder;
5051
import com.elasticinbox.core.model.Mailbox;
5152
import com.elasticinbox.core.model.Message;
52-
import com.elasticinbox.core.model.ReservedLabels;
5353

5454
/**
5555
* Delivery agent implementation
@@ -88,7 +88,12 @@ public Map<MailAddress, DeliveryReturnCode> deliver(MailEnvelope env, final Stri
8888
}
8989

9090
message.setSize((long) env.getSize()); // update message size
91-
message.addLabel(ReservedLabels.INBOX.getId()); // default location
91+
92+
FilterProcessor<Message> processor = new FilterProcessor<Message>();
93+
//processor.add(new NotificationMailFilter());
94+
processor.add(new SpamMailFilter());
95+
processor.add(new DefaultMailFilter());
96+
message = processor.doFilter(message);
9297

9398
logEnvelope(env, message, deliveryId);
9499

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Copyright (c) 2011-2012 Optimax Software Ltd.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* * Neither the name of Optimax Software, ElasticInbox, nor the names
14+
* of its contributors may be used to endorse or promote products derived
15+
* from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
package com.elasticinbox.lmtp.filter;
30+
31+
import com.elasticinbox.core.model.Message;
32+
import com.elasticinbox.core.model.ReservedLabels;
33+
34+
/**
35+
* Default filter which adds Inbox label if no other label assigned by previous
36+
* labels. Should appear at the bottom of the filter chain.
37+
*
38+
* @author Rustam Aliyev
39+
*/
40+
public final class DefaultMailFilter implements Filter<Message>
41+
{
42+
@Override
43+
public Message filter(Message message)
44+
{
45+
// by default store in Inbox
46+
if(message.getLabels().isEmpty()) {
47+
message.addLabel(ReservedLabels.INBOX.getId());
48+
}
49+
50+
return message;
51+
}
52+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright (c) 2011-2012 Optimax Software Ltd.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* * Neither the name of Optimax Software, ElasticInbox, nor the names
14+
* of its contributors may be used to endorse or promote products derived
15+
* from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
package com.elasticinbox.lmtp.filter;
30+
31+
/**
32+
* Filter Interface represents a "Handler" described in Chain of Responsibility
33+
* pattern. Each filter should be processed using {@link FilterProcessor}.
34+
*
35+
* @author Rustam Aliyev
36+
*
37+
* @param <T>
38+
*/
39+
public interface Filter<T>
40+
{
41+
/**
42+
* Processes input and returns modified version
43+
*
44+
* @param input
45+
* @return
46+
*/
47+
T filter(final T input);
48+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Copyright (c) 2011-2012 Optimax Software Ltd.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* * Neither the name of Optimax Software, ElasticInbox, nor the names
14+
* of its contributors may be used to endorse or promote products derived
15+
* from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
package com.elasticinbox.lmtp.filter;
30+
31+
import java.util.LinkedList;
32+
import java.util.List;
33+
34+
/**
35+
* This processor is modified implementation of Chain of Responsibility pattern.
36+
* Filters are applied in the given order. Each filter (handler) processes input
37+
* and passes output to the next one. Final result returned by processor.
38+
*
39+
* @author rustam
40+
*
41+
* @param <T>
42+
*/
43+
public class FilterProcessor<T>
44+
{
45+
private List<Filter<T>> filters;
46+
47+
public FilterProcessor() {
48+
filters = new LinkedList<Filter<T>>();
49+
}
50+
51+
/**
52+
* Add filter to the bottom of the chain
53+
*
54+
* @param filter
55+
*/
56+
public void add(Filter<T> filter) {
57+
filters.add(filter);
58+
}
59+
60+
/**
61+
* Perform filtering process
62+
*
63+
* @param input
64+
* @return
65+
*/
66+
public T doFilter(final T input)
67+
{
68+
T output = input;
69+
for (Filter<T> filter : filters) {
70+
output = filter.filter(output);
71+
}
72+
73+
return output;
74+
}
75+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Copyright (c) 2011-2012 Optimax Software Ltd.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* * Neither the name of Optimax Software, ElasticInbox, nor the names
14+
* of its contributors may be used to endorse or promote products derived
15+
* from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
package com.elasticinbox.lmtp.filter;
30+
31+
import org.slf4j.Logger;
32+
import org.slf4j.LoggerFactory;
33+
34+
import com.elasticinbox.core.model.Message;
35+
import com.elasticinbox.core.model.ReservedLabels;
36+
37+
/**
38+
* This filter detects social network notification messages and stores then
39+
* under Notifications label to keep Inbox clean.
40+
*
41+
* @author Rustam Aliyev
42+
*/
43+
public final class NotificationMailFilter implements Filter<Message>
44+
{
45+
private static final Logger logger = LoggerFactory
46+
.getLogger(NotificationMailFilter.class);
47+
48+
@Override
49+
public Message filter(Message message)
50+
{
51+
try {
52+
String from = message.getFrom().get(0).getAddress();
53+
54+
if (from.matches("(.+)\\+(.+)\\@facebookmail\\.com")
55+
|| from.matches("(.+)\\@facebookappmail\\.com")
56+
|| from.matches("(.+)\\@pages\\.facebookmail\\.com")
57+
|| from.matches("bezotveta\\@odnoklassniki\\.ru")
58+
|| from.matches("admin\\@vkontakte\\.ru")
59+
|| from.matches("(.+)\\-(.+)\\@postmaster\\.twitter\\.com")
60+
|| from.matches("(.+)\\@bounce\\.linkedin\\.com")
61+
|| from.matches("(.+)\\@linkedin\\.com")
62+
|| from.matches("noreply\\-(.+)\\@plus\\.google\\.com")
63+
|| from.matches("notifications\\+(.+)\\@zyngamail\\.com"))
64+
{
65+
logger.debug("Applying filter for NOTIFICATIONS");
66+
message.addLabel(ReservedLabels.NOTIFICATIONS.getId());
67+
}
68+
} catch (Exception ex) {
69+
logger.info("notification type regex parsing error");
70+
}
71+
72+
return message;
73+
}
74+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright (c) 2011-2012 Optimax Software Ltd.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* * Neither the name of Optimax Software, ElasticInbox, nor the names
14+
* of its contributors may be used to endorse or promote products derived
15+
* from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
package com.elasticinbox.lmtp.filter;
30+
31+
import org.slf4j.Logger;
32+
import org.slf4j.LoggerFactory;
33+
34+
import com.elasticinbox.core.message.MimeParser;
35+
import com.elasticinbox.core.model.Message;
36+
import com.elasticinbox.core.model.ReservedLabels;
37+
38+
/**
39+
* Labels message as Spam if respective header is found.
40+
*
41+
* @author Rustam Aliyev
42+
*/
43+
public final class SpamMailFilter implements Filter<Message>
44+
{
45+
private static final Logger logger = LoggerFactory
46+
.getLogger(SpamMailFilter.class);
47+
48+
private final static String MIME_HEADER_SPAM_VALUE = "YES";
49+
50+
@Override
51+
public Message filter(Message message)
52+
{
53+
if (message.getMinorHeader(MimeParser.MIME_HEADER_SPAM) != null
54+
&& message.getMinorHeader(MimeParser.MIME_HEADER_SPAM).equalsIgnoreCase(MIME_HEADER_SPAM_VALUE))
55+
{
56+
logger.debug("Applying filter for SPAM");
57+
message.addLabel(ReservedLabels.SPAM.getId());
58+
}
59+
60+
return message;
61+
}
62+
}

0 commit comments

Comments
 (0)