package com.googlecode.mycontainer.maven.plugin; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import com.googlecode.mycontainer.maven.plugin.util.FileCrawler; /** * @goal us-ascii * @aggregator * @requiresProject false */ public class MycontainerUsAsciiMojo extends AbstractMojo { private static class Entry { private final File file; private final String result; private final String name; public Entry(File file, String result) { this.file = file; this.result = result; this.name = file.getName(); } @Override public String toString() { return name; } } /** * @parameter expression="${mycontainer.us-ascii.filter}" */ private String filter; /** * @parameter */ private List<String> filters; public void execute() throws MojoExecutionException, MojoFailureException { prepareParams(); getLog().info("params: " + filters); final List<Entry> entries = new ArrayList<Entry>(); FileCrawler crawler = new FileCrawler() { @Override protected void found(File file) { if (!filter(file)) { return; } String result = check(file); if (result != null) { getLog().error("non us-ascii file found: " + file + " (" + result + ")"); entries.add(new Entry(file, result)); } } }; crawler.crawl(new File(".")); if (!entries.isEmpty()) { throw new MojoFailureException("non us-ascii files found: " + entries.size()); } } private boolean filter(File file) { for (String filter : filters) { int idx = filter.indexOf(":"); String type = filter.substring(0, idx); String value = filter.substring(idx + 1); String path = file.getPath(); path = path.replaceAll("\\\\", "/"); boolean matches = path.matches(value); if ("include".equals(type) && matches) { return true; } if ("exclude".equals(type) && matches) { return false; } } return false; } private void prepareParams() { if (filters == null) { filters = new ArrayList<String>(); } if (filter != null) { filters.add(filter); } if (filters.isEmpty()) { filters.add(0, "include:.*"); } } private String check(File file) { if (file.isDirectory()) { return null; } InputStream in = null; try { in = new FileInputStream(file); return check(in); } catch (IOException e) { throw new RuntimeException(e); } finally { close(in); } } private String check(InputStream in) throws IOException { byte[] buffer = new byte[1024 * 100]; while (true) { int read = in.read(buffer); if (read < 0) { return null; } String ret = check(buffer, 0, read); if (ret != null) { return ret; } } } private String check(byte[] buffer, int offset, int limit) { for (int i = 0; i < limit; i++) { byte b = buffer[offset + i]; int num = 0xFF & b; if (num != 9 && num != 10 && num != 13 && (num < 20 || num > 127)) { return "non-us-acii, byte: " + " 0x" + hex(num) + " (" + num + ")"; } } return null; } private String hex(int num) { String str = Integer.toHexString(num).toUpperCase(); if (str.length() == 1) { str = "0" + str; } return str; } private void close(Closeable c) { if (c != null) { try { c.close(); } catch (Exception e) { getLog().error("error closing", e); } } } }