/*
* Copyright 2007-2009 Medsea Business Solutions S.L.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.medsea.mimeutil.detector;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import eu.medsea.mimeutil.MimeException;
import eu.medsea.mimeutil.MimeType;
import eu.medsea.mimeutil.MimeUtil;
/**
* Get the content type for a file extension as stored in the Windows Registry
* The extensions are stored at "HKEY_CLASSES_ROOT"
* <p>
* This MimeDetector will only operate on Windows machines. On any other platform
* the methods throw a UnsupportedOperationException (These are swallowed by the MimeUtil class)
* Therefore, it is perfectly acceptable to register this MimeDetector with MimeUtil and it
* will only be used on a Windows Platform. On all other platforms it will just be ignored.
* </p>
* <p>
* To register this MimeDetector use<br/>
* <code>MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.WindowsRegistryMimeDetector");</code>
* </p>
* <p>
* The Collection returned from the getMimeTypesXXX(...) Methods with contain either a single MimeType
* or the collection will be empty.
* </p>
* <p>
* This MimeDetector only performs file extension mapping, so the methods taking an InputStream and byte array
* throw UnsupportedOperationException
* </p>
*
* @author Steven McArdle
*
*/
public class WindowsRegistryMimeDetector extends MimeDetector {
private static final String REG_QUERY = "reg query ";
private static final String CONTENT_TYPE = "\"Content Type\"";
private static final boolean isWindows = System.getProperty("os.name").startsWith("Windows");
public String getDescription() {
return "Get the MIME types of file extensions from the Windows Registry. Will be inafective on non-Windows machines.";
}
public Collection getMimeTypesFile(File file)
throws UnsupportedOperationException {
try {
return getMimeTypesURL(file.toURI().toURL());
}catch(Exception e) {
throw new MimeException(e);
}
}
public Collection getMimeTypesFileName(String fileName)
throws UnsupportedOperationException {
return getMimeTypesFile(new File(fileName));
}
public Collection getMimeTypesURL(URL url)
throws UnsupportedOperationException {
Collection mimeTypes = new ArrayList();
if(!isWindows) {
return mimeTypes;
}
String contentType = getContentType(MimeUtil.getExtension(url.getPath()));
if(contentType != null && contentType.length() > 0) {
mimeTypes.add(new MimeType(contentType));
}
return mimeTypes;
}
/**
* Content detection not supported
*/
public Collection getMimeTypesByteArray(byte[] data)
throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"WindowsRegistryMimeDetector does not support detection from byte arrays.");
}
/**
* Content detection not supported
*/
public Collection getMimeTypesInputStream(InputStream in)
throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"WindowsRegistryMimeDetector does not support detection from InputStreams.");
}
private String getContentType(String extension) {
if (extension == null || extension.length() < 1) {
return null;
}
try {
String query = REG_QUERY + "\"HKEY_CLASSES_ROOT\\." + extension + "\" /v " + CONTENT_TYPE;
Process process = Runtime.getRuntime().exec(query);
StreamReader reader = new StreamReader(process.getInputStream());
reader.start();
process.waitFor();
reader.join();
String result = reader.getResult();
int p = result.indexOf("REG_SZ");
if (p == -1)
return null;
return result.substring(p + "REG_SZ".length()).trim();
} catch (Exception e) {
return null;
}
}
static class StreamReader extends Thread {
private InputStream is;
private StringWriter sw;
StreamReader(InputStream is) {
this.is = is;
sw = new StringWriter();
}
public void run() {
try {
int c;
while ((c = is.read()) != -1)
sw.write(c);
} catch (IOException e) {
;
}
}
String getResult() {
return sw.toString();
}
}
}