/* $Revision: 6707 $ $Author: egonw $ $Date: 2006-07-30 16:38:18 -0400 (Sun, 30 Jul 2006) $ * * Copyright (C) 2006-2008 Egon Willighagen <egonw@users.sf.net> * * Contact: cdk-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * All we ask is that proper credit is given for our work, which includes * - but is not limited to - adding the above copyright notice to the beginning * of your source code files, and to any copyright notice that you may distribute * with programs based on this work. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package net.sf.cdk.tools.copyright; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author egonw */ public class CheckCopyrightStatements { private enum CopyrightField { YEAR_INFO, AUTHOR_NAME, AUTHOR_EMAIL } public void processJavaSourceFiles(File path) { if (path.isDirectory()) { for (File file : path.listFiles()) { processJavaSourceFiles(file); } } else if (path.isFile() && path.getPath().endsWith(".java") && !path.getPath().contains("net" + File.separator + "sf")) { Map<String,List<Map<CopyrightField,String>>> copyrights = getCopyrightInfo(path); if (copyrights != null) checkCopyrightStatements(copyrights); } } private void checkCopyrightStatements(Map<String,List<Map<CopyrightField, String>>> copyrights ) { String fileName = copyrights.keySet().iterator().next(); List<Map<CopyrightField, String>> copyrightList = copyrights.get(fileName); if (copyrightList.size() == 0) { System.out.println(fileName + ": missing copyright line."); } for (Map<CopyrightField,String> holder : copyrightList) { // check year if (holder.get(CopyrightField.YEAR_INFO) == null) { System.out.println(fileName + ": missing copyright year."); } // check copyright holder if (holder.get(CopyrightField.AUTHOR_NAME) == null) { System.out.println(fileName + ": missing copyright holder name."); } else { String holderName = holder.get(CopyrightField.AUTHOR_NAME); // check holder != CDK if (holderName.contains("Chemistry") && holderName.contains("Development") && holderName.contains("Kit")) { System.out.println(fileName + ": copyright is not a legal entity"); } else if (holder.get(CopyrightField.AUTHOR_EMAIL) == null) { System.out.println(fileName + ": copyright holder is not identified by an email address"); } } } } public Map<String,List<Map<CopyrightField,String>>> getCopyrightInfo(File file) { boolean autoGenerated = false; Map<String,List<Map<CopyrightField,String>>> results = new HashMap<String, List<Map<CopyrightField,String>>>(); List<Map<CopyrightField,String>> copyrights = new ArrayList<Map<CopyrightField,String>>(); try { BufferedReader reader = new BufferedReader( new FileReader(file) ); String line = null; boolean foundPackageClause = false; while ((line = reader.readLine()) != null && !foundPackageClause) { if (line.toLowerCase().contains("do not edit")) { return null; }; foundPackageClause = line.contains("package"); if (line.contains("Copyright")) { Map<CopyrightField,String> copyrightProperties = new HashMap<CopyrightField, String>(); Pattern copyrightPattern = Pattern.compile(".*Copyright\\s*\\(C\\)\\s*(.*)"); Matcher generalMatch = copyrightPattern.matcher(line); if (generalMatch.matches()) { String interestingInfo = generalMatch.group(1).trim(); String year = null; String author = null; String email = null; Pattern yearsPattern = Pattern.compile("(\\d{4}-\\d{4}).*"); Pattern yearPattern = Pattern.compile("(\\d{4}).*"); Matcher yearMatch = yearPattern.matcher(interestingInfo); Matcher yearsMatch = yearsPattern.matcher(interestingInfo); if (yearsMatch.matches() || yearMatch.matches()) { year = yearsMatch.matches() ? yearsMatch.group(1) : yearMatch.group(1); copyrightProperties.put(CopyrightField.YEAR_INFO, year); if (interestingInfo.length() > year.length()) { interestingInfo = interestingInfo.substring(year.length()+1).trim(); } else { interestingInfo = ""; } } if (year != null) { Pattern authorPattern = Pattern.compile("([^<]*).*"); Matcher authorMatch = authorPattern.matcher(interestingInfo); if (authorMatch.matches()) { author = authorMatch.group(1).trim(); copyrightProperties.put(CopyrightField.AUTHOR_NAME, author); if (interestingInfo.length() > author.length()) { interestingInfo = interestingInfo.substring(author.length()+1).trim(); } else { interestingInfo = ""; } } } if (author != null) { Pattern emailPattern = Pattern.compile("<([^>]*).*"); Matcher emailMatch = emailPattern.matcher(interestingInfo); if (emailMatch.matches()) { email = emailMatch.group(1).trim(); copyrightProperties.put(CopyrightField.AUTHOR_EMAIL, email); } } } copyrights.add(copyrightProperties); } } } catch (Exception e) { e.printStackTrace(); } results.put(toAPIPath(file.getPath()), copyrights); return results; } public static void main(String[] args) { CheckCopyrightStatements processor = new CheckCopyrightStatements(); processor.processJavaSourceFiles(new File("src/main")); } private String toAPIPath(String className) { className = className.replaceFirst("src" + File.separator + "main" + File.separator, ""); className = className.replaceFirst(".java", ""); StringBuffer sb = new StringBuffer(); for (int i=0; i<className.length(); i++) { if (className.charAt(i) == File.separatorChar) { sb.append('.'); } else { sb.append(className.charAt(i)); } } return sb.toString(); } }