You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by vi...@apache.org on 2004/07/11 22:54:44 UTC
cvs commit: james-server/src/java/org/apache/james/transport/matchers AttachmentFileNameIs.java
vincenzo 2004/07/11 13:54:44
Modified: src/java/org/apache/james/transport/matchers Tag:
branch_2_1_fcs AttachmentFileNameIs.java
Log:
Added:
1) ability to do analysis inside zip file attachments;
2) ability to log some info if debug is requested.
To analyze zip files code
... match="AttachmentFileNameIs=-z ...";
to debug code
... match="AttachmentFileNameIs=-d ...".
Revision Changes Path
No revision
No revision
1.1.2.5 +105 -20 james-server/src/java/org/apache/james/transport/matchers/AttachmentFileNameIs.java
Index: AttachmentFileNameIs.java
===================================================================
RCS file: /home/cvs/james-server/src/java/org/apache/james/transport/matchers/AttachmentFileNameIs.java,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -r1.1.2.4 -r1.1.2.5
--- AttachmentFileNameIs.java 15 Mar 2004 03:54:21 -0000 1.1.2.4
+++ AttachmentFileNameIs.java 11 Jul 2004 20:54:44 -0000 1.1.2.5
@@ -24,26 +24,44 @@
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeMessage;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Locale;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipEntry;
+import java.io.InputStream;
/**
* <P>Checks if at least one attachment has a file name which matches any
- * element of a comma-separated list of file name masks.
- * The match is case insensitive.</P>
+ * element of a comma-separated or space-separated list of file name masks.</P>
+ * <P>Syntax: <CODE>match="AttachmentFileNameIs=[-d] [-z] <I>masks</I>"</CODE></P>
+ * <P>The match is case insensitive.</P>
* <P>File name masks may start with a wildcard '*'.</P>
* <P>Multiple file name masks can be specified, e.g.: '*.scr,*.bat'.</P>
+ * <P>If '<CODE>-d</CODE>' is coded, some debug info will be logged.</P>
+ * <P>If '<CODE>-z</CODE>' is coded, the check will be non-recursively applied
+ * to the contents of any attached '*.zip' file.</P>
*
* @version CVS $Revision$ $Date$
* @since 2.2.0
*/
public class AttachmentFileNameIs extends GenericMatcher {
+
+ /** Unzip request parameter. */
+ protected static final String UNZIP_REQUEST_PARAMETER = "-z";
+
+ /** Debug request parameter. */
+ protected static final String DEBUG_REQUEST_PARAMETER = "-d";
+
+ /** Match string for zip files. */
+ protected static final String ZIP_SUFFIX = ".zip";
+
/**
- * represents a single parsed file name mask
+ * represents a single parsed file name mask.
*/
private static class Mask {
/** true if the mask starts with a wildcard asterisk */
@@ -53,18 +71,37 @@
public String matchString;
}
+ /**
+ * Controls certain log messages.
+ */
+ protected boolean isDebug = false;
+
/** contains ParsedMask instances, setup by init */
private Mask[] masks = null;
- /** parses the condition */
+ /** True if unzip is requested. */
+ protected boolean unzipIsRequested;
+
public void init() throws MessagingException {
- /** sets up fileNameMasks variable by parsing the condition */
+ /* sets up fileNameMasks variable by parsing the condition */
StringTokenizer st = new StringTokenizer(getCondition(), ", ", false);
ArrayList theMasks = new ArrayList(20);
while (st.hasMoreTokens()) {
- Mask mask = new Mask();
String fileName = st.nextToken();
+
+ // check possible parameters at the beginning of the condition
+ if (theMasks.size() == 0 && fileName.equalsIgnoreCase(UNZIP_REQUEST_PARAMETER)) {
+ unzipIsRequested = true;
+ log("zip file analysis requested");
+ continue;
+ }
+ if (theMasks.size() == 0 && fileName.equalsIgnoreCase(DEBUG_REQUEST_PARAMETER)) {
+ isDebug = true;
+ log("debug requested");
+ continue;
+ }
+ Mask mask = new Mask();
if (fileName.startsWith("*")) {
mask.suffixMatch = true;
mask.matchString = fileName.substring(1);
@@ -72,8 +109,7 @@
mask.suffixMatch = false;
mask.matchString = fileName;
}
- mask.matchString = mask.matchString.toLowerCase(Locale.US);
- mask.matchString = mask.matchString.trim();
+ mask.matchString = cleanFileName(mask.matchString);
theMasks.add(mask);
}
masks = (Mask[])theMasks.toArray(new Mask[0]);
@@ -91,7 +127,7 @@
MimeMessage message = mail.getMessage();
Object content;
- /**
+ /*
* if there is an attachment and no inline text,
* the content type can be anything
*/
@@ -105,8 +141,7 @@
for (int i = 0; i < multipart.getCount(); i++) {
try {
Part part = multipart.getBodyPart(i);
- String fileName = part.getFileName();
- if (fileName != null && matchFound(fileName)) {
+ if (matchFound(part)) {
return mail.getRecipients(); // matching file found
}
} catch (MessagingException e) {
@@ -114,8 +149,7 @@
} // ignore any messaging exception and process next bodypart
}
} else {
- String fileName = message.getFileName();
- if (fileName != null && matchFound(fileName)) {
+ if (matchFound(message)) {
return mail.getRecipients(); // matching file found
}
}
@@ -131,13 +165,32 @@
return null; // no matching attachment found
}
- /*
+ /**
+ * Checks if <I>part</I> matches with at least one of the <CODE>masks</CODE>.
+ */
+ protected boolean matchFound(Part part) throws MessagingException, IOException {
+ String fileName = part.getFileName();
+ if (fileName != null) {
+ fileName = cleanFileName(fileName);
+ // check the file name
+ if (matchFound(fileName)) {
+ if (isDebug) {
+ log("matched " + fileName);
+ }
+ return true;
+ }
+ if (unzipIsRequested && fileName.endsWith(ZIP_SUFFIX)) {
+ return matchFoundInZip(part);
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Checks if <I>fileName</I> matches with at least one of the <CODE>masks</CODE>.
*/
- private boolean matchFound(String fileName) {
- fileName = fileName.toLowerCase(Locale.US);
- fileName = fileName.trim();
-
+ protected boolean matchFound(String fileName) {
for (int j = 0; j < masks.length; j++) {
boolean fMatch;
Mask mask = masks[j];
@@ -148,9 +201,41 @@
} else {
fMatch = fileName.equals(mask.matchString);
}
- if (fMatch) return true; // matching file found
+ if (fMatch) {
+ return true; // matching file found
+ }
}
return false;
+ }
+
+ /**
+ * Checks if <I>part</I> is a zip containing a file that matches with at least one of the <CODE>masks</CODE>.
+ */
+ protected boolean matchFoundInZip(Part part) throws MessagingException, IOException {
+ ZipInputStream zis = new ZipInputStream(part.getInputStream());
+
+ try {
+ while (zis.available() > 0) {
+ ZipEntry zipEntry = zis.getNextEntry();
+ String fileName = zipEntry.getName();
+ if (matchFound(fileName)) {
+ if (isDebug) {
+ log("matched " + part.getFileName() + "(" + fileName + ")");
+ }
+ return true;
+ }
+ }
+ return false;
+ } finally {
+ zis.close();
+ }
+ }
+
+ /**
+ * Transforms <I>fileName<I> in a trimmed lowercase string usable for matching agains the masks.
+ */
+ protected String cleanFileName(String fileName) {
+ return fileName.toLowerCase(Locale.US).trim();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org