/* * 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(); } } }