/******************************************************************************* * Copyright (c) 2012 BundleMaker Project Team * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann - initial API and implementation ******************************************************************************/ package org.bundlemaker.core.ui.projecteditor.filebased; import java.io.File; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.bundlemaker.core.common.ResourceType; import org.bundlemaker.core.project.VariablePath; import org.eclipse.core.runtime.CoreException; /** * @author Nils Hartmann (nils@nilshartmann.net) * */ public class ContentTypeDetector { /** * A {@link Pattern} matching (file) names containing 'src' or 'source' */ private final Pattern sourceNamePattern = Pattern.compile("(.*\\W)?(src|source)(\\W.*)?"); public ResourceType detectContentType(VariablePath path) { try { File file = path.getAsFile(); return detectContentType(file); } catch (CoreException e) { return guessContentTypeFromFileName(path.getUnresolvedPath().toString()); } } /** * Tries to determine the {@link ResourceType} of the specified file. * * <p> * If the content type cannot be determined, {@link ResourceType#BINARY} is assumed. * * @param file * a file or directory * * @return the content type. Never null */ public ResourceType detectContentType(File file) { ResourceType result = null; if (file.isDirectory()) { result = detectContentTypeFromDirectory(file); } if (file.isFile()) { result = detectContentTypeFromFile(file); } if (result == null) { // check if file name contains 'source' or 'src' result = guessContentTypeFromFileName(file.getAbsolutePath()); } return result; } /** * @param file * @return */ protected ResourceType detectContentTypeFromDirectory(File file) { ResourceType result = null; File[] allFiles = file.listFiles(); List<File> directories = new LinkedList<File>(); for (File fileInDirectory : allFiles) { if (fileInDirectory.isDirectory()) { // save subdirectories in case we need to recursively scan them for files directories.add(fileInDirectory); } else { String fileName = fileInDirectory.getName(); if (isJavaClassFileName(fileName)) { // class file found: this jar is probably an archive containing binaries result = ResourceType.BINARY; break; } if (isJavaSourceFileName(fileName)) { // class file found: this jar is probably an archive containing binaries result = ResourceType.SOURCE; break; } } } if (result == null) { for (File subDirectory : directories) { result = detectContentTypeFromDirectory(subDirectory); if (result != null) { break; } } } return result; } protected boolean isJavaSourceFileName(String fileName) { return (fileName != null && fileName.toLowerCase().endsWith(".java")); } protected boolean isJavaClassFileName(String fileName) { return (fileName != null && fileName.toLowerCase().endsWith(".class")); } /** * @param file * @return */ protected ResourceType detectContentTypeFromFile(File file) { JarFile jarFile = null; ResourceType result = ResourceType.BINARY; try { jarFile = new JarFile(file); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String fileName = entry.getName(); if (isJavaClassFileName(fileName)) { // class file found: this jar is probably an archive containing binaries result = ResourceType.BINARY; break; } if (isJavaSourceFileName(fileName)) { // class file found: this jar is probably an archive containing binaries result = ResourceType.SOURCE; break; } } } catch (Exception ex) { // for whatever reason we're not able to read the file: // guess content type based on the file name result = guessContentTypeFromFileName(file.getAbsolutePath()); } finally { if (jarFile != null) { try { jarFile.close(); } catch (Exception ex) { // ignore } } } return result; } /** * @param name * @return */ protected ResourceType guessContentTypeFromFileName(String name) { // Create the matcher Matcher matcher = sourceNamePattern.matcher(name.toLowerCase()); // boolean sourceFileName = matcher.matches(); if (sourceFileName) { return ResourceType.SOURCE; } return ResourceType.BINARY; } public static void main(String[] args) { File f = new File("/Users/nils/develop/bundlemaker/bundlemaker-ui-workspace/BM-JEdit/libs/jedit-abc.zip"); ResourceType ct = new ContentTypeDetector().detectContentType(f); System.out.println("/Users/nils/develop/bundlemaker/bundlemaker-ui-workspace/BM-JEdit/libs/jedit-abc.zip: " + ct); ct = new ContentTypeDetector().detectContentType(new File( "/Users/nils/develop/bundlemaker/bundlemaker-ui-workspace/BM-JEdit/libs/jedit.jar")); System.out.println("/Users/nils/develop/bundlemaker/bundlemaker-ui-workspace/BM-JEdit/libs/jedit.jar: " + ct); ct = new ContentTypeDetector().detectContentType(new File( "/Users/nils/develop/bundlemaker/bundlemaker-ui-workspace/core/src")); System.out.println("/Users/nils/develop/bundlemaker/bundlemaker-ui-workspace/core/src: " + ct); ct = new ContentTypeDetector().detectContentType(new File( "/Users/nils/develop/bundlemaker/bundlemaker-ui-workspace/core/bin")); System.out.println("/Users/nils/develop/bundlemaker/bundlemaker-ui-workspace/core/bin: " + ct); // // Pattern p = Pattern.compile("(.*\\W)?(src|source)(\\W.*)?"); // // isMatching(p, "asrca"); // isMatching(p, "AsrcA"); // isMatching(p, "/src/aa"); // isMatching(p, "src/aa"); // isMatching(p, "src"); // isMatching(p, "src.jar"); // // isMatching(p, "asourcea"); // isMatching(p, "AsourceA"); // isMatching(p, "/source/aa"); // isMatching(p, "source/aa"); // isMatching(p, "source"); // isMatching(p, "source.jar"); } // private static void isMatching(Pattern p, String value) { // Matcher m = p.matcher(value.toLowerCase()); // boolean b = m.matches(); // // System.out.printf("'%s' matches pattern: %s%n", value, b); // } }