1e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera/* 2e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 3e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 5e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * This code is free software; you can redistribute it and/or modify it 6e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * under the terms of the GNU General Public License version 2 only, as 7e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * published by the Free Software Foundation. Oracle designates this 8e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * particular file as subject to the "Classpath" exception as provided 9e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * by Oracle in the LICENSE file that accompanied this code. 10e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 11e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * This code is distributed in the hope that it will be useful, but WITHOUT 12e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * version 2 for more details (a copy is included in the LICENSE file that 15e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * accompanied this code). 16e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 17e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * You should have received a copy of the GNU General Public License version 18e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 2 along with this work; if not, write to the Free Software Foundation, 19e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 21e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * or visit www.oracle.com if you need additional information or have any 23e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * questions. 24e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 25e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 26e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmerapackage sun.nio.fs; 27e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 28e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.nio.file.Path; 29e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.nio.file.spi.FileTypeDetector; 30e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.util.Locale; 31e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.io.IOException; 32e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 33e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera/** 34e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Base implementation of FileTypeDetector 35e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 36e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 37e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmerapublic abstract class AbstractFileTypeDetector 38e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera extends FileTypeDetector 39e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera{ 40e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera protected AbstractFileTypeDetector() { 41e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera super(); 42e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 43e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 44e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera /** 45e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Invokes the appropriate probe method to guess a file's content type, 46e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * and checks that the content type's syntax is valid. 47e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 48e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 49e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public final String probeContentType(Path file) throws IOException { 50e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (file == null) 51e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new NullPointerException("'file' is null"); 52e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera String result = implProbeContentType(file); 53e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return (result == null) ? null : parse(result); 54e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 55e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 56e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera /** 57e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Probes the given file to guess its content type. 58e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 59e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera protected abstract String implProbeContentType(Path file) 60e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throws IOException; 61e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 62e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera /** 63e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Parses a candidate content type into its type and subtype, returning 64e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * null if either token is invalid. 65e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 66e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera private static String parse(String s) { 67e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int slash = s.indexOf('/'); 68e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int semicolon = s.indexOf(';'); 69e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (slash < 0) 70e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return null; // no subtype 71e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera String type = s.substring(0, slash).trim().toLowerCase(Locale.ENGLISH); 72e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!isValidToken(type)) 73e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return null; // invalid type 74e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera String subtype = (semicolon < 0) ? s.substring(slash + 1) : 75e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera s.substring(slash + 1, semicolon); 76e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera subtype = subtype.trim().toLowerCase(Locale.ENGLISH); 77e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!isValidToken(subtype)) 78e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return null; // invalid subtype 79e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera StringBuilder sb = new StringBuilder(type.length() + subtype.length() + 1); 80e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera sb.append(type); 81e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera sb.append('/'); 82e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera sb.append(subtype); 83e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return sb.toString(); 84e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 85e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 86e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera /** 87e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Special characters 88e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 89e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera private static final String TSPECIALS = "()<>@,;:/[]?=\\\""; 90e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 91e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera /** 92e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Returns true if the character is a valid token character. 93e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 94e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera private static boolean isTokenChar(char c) { 95e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return (c > 040) && (c < 0177) && (TSPECIALS.indexOf(c) < 0); 96e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 97e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 98e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera /** 99e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Returns true if the given string is a legal type or subtype. 100e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 101e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera private static boolean isValidToken(String s) { 102e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int len = s.length(); 103e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (len == 0) 104e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return false; 105e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera for (int i = 0; i < len; i++) { 106e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!isTokenChar(s.charAt(i))) 107e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return false; 108e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 109e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return true; 110e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 111e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera} 112