|
Problem DescriptionApplications often need to work out the type of a file to see if it is a text file, an HTML document, an executable, etc. This can be done in two ways:
Utilities such as the Unix file command use the second method and have a complex description file (such as /etc/magic or /usr/share/magic ) to aid in this. Many other applications, such as Web browsers, mail readers, and even some operating systems, use the first method and work out a file's type based on its name. A common way of classifying files is into MIME types, such as text/plain and image/gif . There are tables of "official" MIME types ( unofficial ones can be added on an ad hoc basis), and there are also tables of mappings from filename endings to corresponding MIME types. These tables have entries such as these: application/postscript ai eps ps application/rtf rtf application/zip zip image/gif gif image/jpeg jpeg jpg jpe text/html html htm text/plain txt These tables are stored in files for applications to access. Storing these tables separately from the applications that would use them is considered bad from the object-oriented point of view, since each application would need to have code to interpret the tables. Also, the multiplicity of these tables and the ability of users to modify them makes this a maintenance problem. It would be better to encapsulate at least the filename to MIME type mapping table in an object. We could define a MIME class as follows : package standalone; /** * MIMEType.java */ public class MIMEType { /** * A MIME type is made up of 2 parts * contentType/subtype */ protected String contentType; protected String subtype; public MIMEType(String type) { int slash = type.indexOf('/'); contentType = type.substring(0, slash1); subtype = type.substring(slash+1, type.length()); } public MIMEType(String contentType, String subtype) { this.contentType = contentType; this.subtype = subtype; } public String toString() { return contentType + "/" + subtype; } } // MIMEType We could then define a mapping class like this: package standalone; /** * FileClassifier.java */ public class FileClassifier { static MIMEType getMIMEType(String fileName) { if (fileName.endsWith(".gif")) { return new MIMEType("image", "gif"); } else if (fileName.endsWith(".jpeg")) { return new MIMEType("image", "jpeg"); } else if (fileName.endsWith(".mpg")) { return new MIMEType("video", "mpeg"); } else if (fileName.endsWith(".txt")) { return new MIMEType("text", "plain"); } else if (fileName.endsWith(".html")) { return new MIMEType("text", "html"); } else // fill in lots of other types, // but eventually give up and return null; } } // FileClassifier This mapping class has no constructors, because it just acts as a lookup table via its static method getMIMEType() . Applications can make use of these classes as they stand, by simply compiling them and having the class files available at run time. This would still result in duplication throughout JVMs, possible multiple copies of the class files, and potentially severe maintenance problems if applications need to be recompiled, so it might be better to have the FileClassifier as a network service. Let's consider what would be involved in this. |