/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.sysml.validation; import java.io.BufferedReader; import java.io.BufferedOutputStream; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; import org.apache.commons.io.FileUtils; /** * Checks that all jar files included in the distribution are mentioned in the LICENSE file * and that all jars mentioned in the LICENSE are in the distribution. */ public class ValidateLicAndNotice { public static String[] fileTypes = {Constants.JAR, Constants.DLL, Constants.EXP, Constants.LIB, Constants.PDB, Constants.EXE}; // Zip Distribution directory. private String strDistroDir = "../../../target/release/incubator-systemml/target/"; static final String[][] packageLicenses = { {"org/antlr", "ANTLR 4 Runtime (http://www.antlr.org/antlr4-runtime) org.antlr:antlr4-runtime:4.5.3"}, {"org/apache/wink/json4j","Apache Wink :: JSON4J (http://www.apache.org/wink/wink-json4j/) org.apache.wink:wink-json4j:1.4"} }; public static HashMap<String, String[][]> hmJSLicenses = new HashMap<String, String[][]>(); static { String [][] strTemp1 = {{"Bootstrap v3.3.6", "Copyright (c) 2011-2015 Twitter, Inc.", "false"}}; hmJSLicenses.put("bootstrap.min.js", strTemp1); String [][] strTemp2 = {{"Normalize v3.0.3", "Copyright (c) Nicolas Gallagher and Jonathan Neal", "false"}}; hmJSLicenses.put("bootstrap.min.css", strTemp2); String [][] strTemp3 = {{"AnchorJS v1.1.1", "Copyright (c) 2015 Bryan Braun", "false"}}; hmJSLicenses.put("anchor.min.js", strTemp3); String [][] strTemp4 = {{"jQuery v1.12.0", "(c) jQuery Foundation", "false"}, {"jQuery v1.12.0", "Copyright jQuery Foundation and other contributors, https://jquery.org/", "false"}}; hmJSLicenses.put("jquery-1.12.0.min.js", strTemp4); String [][] strTemp5 = {{"Pygments", "Copyright (c) 2006-2017 by the respective authors (see AUTHORS file).", "false"}}; hmJSLicenses.put("pygments-default.css", strTemp5); } public ValidateLicAndNotice() { } public ValidateLicAndNotice(String strDistroDir) { setDistroDir(strDistroDir); } public String getDistroDir() { return strDistroDir; } public void setDistroDir(String strDistroDir) { this.strDistroDir = strDistroDir; } /** * This will validate all zip and tgz from distribution location. * * @return Returns the output code */ public int validate() throws Exception { int retCode = Constants.SUCCESS, retCodeForAllFileTypes = Constants.SUCCESS, retCodeAll = Constants.SUCCESS; File distroRoot = new File( getDistroDir()); File libDirectory = distroRoot; if (!libDirectory.exists()) { Utility.debugPrint(Constants.DEBUG_ERROR, "Distribution folder '" + libDirectory.getAbsoluteFile().toString() + "' does not exist."); return Constants.NO_ZIP_TGZ; } File outTempDir = File.createTempFile("outTemp", ""); outTempDir.delete(); outTempDir.mkdir(); List<String> zips = getZipsInDistro(libDirectory); if(zips.size() == 0) { Utility.debugPrint(Constants.DEBUG_ERROR, "Can't find zip/tgz files in folder: " + libDirectory.getAbsoluteFile().toString()); return Constants.NO_ZIP_TGZ; } for (String zipFile: zips) { retCodeForAllFileTypes = Constants.SUCCESS; Utility.debugPrint(Constants.DEBUG_INFO, "======================================================================================"); Utility.debugPrint(Constants.DEBUG_INFO, "Validating zip file : " + zipFile + " ..."); for (String fileType: fileTypes) { retCode = Constants.SUCCESS; List<String> filesAll = null; // Extract license/notice only at first time in all filetypes validation for a given zip. if(fileType == Constants.JAR) { if (!ValidateLicAndNotice.extractFile(libDirectory + "/" + zipFile, Constants.LICENSE, outTempDir.getAbsolutePath(), true)) return Constants.FAILED_TO_EXTRACT; if (!ValidateLicAndNotice.extractFile(libDirectory + "/" + zipFile, Constants.NOTICE, outTempDir.getAbsolutePath(), true)) return Constants.FAILED_TO_EXTRACT; } filesAll = getFiles(libDirectory + "/" + zipFile, fileType); File licenseFile = new File(outTempDir, Constants.LICENSE); List<String> files = new ArrayList<String>(); List<String> fileSysml = new ArrayList<String>(); for (String file : filesAll) { int sysmlLen = Constants.SYSTEMML_NAME.length(); String strBegPart = file.substring(0, sysmlLen); if (strBegPart.compareToIgnoreCase(Constants.SYSTEMML_NAME) != 0) files.add(file); else fileSysml.add(file); } List<String> bad2 = getLICENSEFilesNotInList(licenseFile, files, fileType); if (bad2.size() > 0) { Utility.debugPrint(Constants.DEBUG_WARNING,"Files in LICENSE but not in Distribution: " + bad2); retCode += Constants.FILE_NOT_IN_ZIP; } List<String> bad1 = getFilesNotInLICENSE(licenseFile, files, fileType); if (bad1.size() > 0) { Utility.debugPrint(Constants.DEBUG_ERROR,"Files in distribution but not in LICENSE: " + bad1); retCode += Constants.FILE_NOT_IN_LIC; } // Validate shaded jar and notice only one time for each zip/tgz file. if(fileType == Constants.JAR) { for (String file : fileSysml) retCode += ValidateLicAndNotice.validateShadedLic(libDirectory + "/" + zipFile, file, outTempDir.getAbsolutePath()); if (!validateNotice(outTempDir.getAbsolutePath()+"/"+Constants.NOTICE)) { Utility.debugPrint(Constants.DEBUG_ERROR, "Notice validation falied, please check notice file manually in this zip/tgz file."); retCode += Constants.INVALID_NOTICE; } if (!validateJSCssLicense(licenseFile, libDirectory + "/" + zipFile)) { Utility.debugPrint(Constants.DEBUG_ERROR, "JS/CSS license validation falied, please check license file manually in this zip/tgz file."); retCode += Constants.JS_CSS_LIC_NOT_EXIST; } } if (retCode == Constants.SUCCESS) Utility.debugPrint(Constants.DEBUG_INFO3, "Validation of file type '." + fileType + "' in zip/tgz file : " + zipFile + " completed successfully."); else { Utility.debugPrint(Constants.DEBUG_ERROR, "License/Notice validation failed for zip/tgz file " + zipFile + " with error code " + retCode + ", please validate file manually."); retCodeForAllFileTypes = Constants.FAILURE; } } if(retCodeForAllFileTypes == Constants.SUCCESS) Utility.debugPrint(Constants.DEBUG_INFO, "Validation of zip/tgz file : " + zipFile + " completed successfully."); retCodeAll = retCodeForAllFileTypes != Constants.SUCCESS?Constants.FAILURE:retCodeAll; } Utility.debugPrint(Constants.DEBUG_INFO, "======================================================================================"); FileUtils.deleteDirectory(outTempDir); return retCodeAll; } /** * This will validate objects (class files) from jar file within a zip file. * * @param zipFileName is the name of zip file from which set of class packages will be returned. * @param fileName is the name of the file within zip (jar) file to validate list of packages within. * @param outTempDir is the temporary directory name. * @return Success or Failure code */ public static int validateShadedLic(String zipFileName, String file, String outTempDir) throws Exception { File outTempDir2 = new File (outTempDir + "/" + "2"); outTempDir2.mkdir(); if(!ValidateLicAndNotice.extractFile(zipFileName, file, outTempDir2.getAbsolutePath(), false)) return Constants.FAILED_TO_EXTRACT; if(!ValidateLicAndNotice.extractFile(outTempDir2.getAbsolutePath()+"/"+file, Constants.LICENSE, outTempDir2.getAbsolutePath(), true)) return Constants.FAILED_TO_EXTRACT; HashMap<String, Boolean> hashMapPackages = getPackagesFromZip(outTempDir2.getAbsolutePath() + "/" + file); for (String packageName: hashMapPackages.keySet()) Utility.debugPrint(Constants.DEBUG_CODE, "Package: " + packageName + " Licensed: " + hashMapPackages.get(packageName)); int iRetCode = ValidateLicAndNotice.validatePackages(outTempDir2.getAbsolutePath()+"/"+Constants.LICENSE, hashMapPackages); FileUtils.deleteDirectory(outTempDir2); return iRetCode; } /** * This will validate objects (class files) against license file. * * @param licenseFile is the name of the license file. * @param hashMapPackages is the list of package names to be validated for license. * @return Success or Failure code */ public static int validatePackages(String licenseFile, HashMap<String, Boolean> hashMapPackages) throws Exception { int iRetCode = Constants.SUCCESS; BufferedReader reader = new BufferedReader(new FileReader(licenseFile)); String line = null; HashSet <String> packageValidLic = new HashSet<String>(); while ((line = reader.readLine()) != null) { line = line.trim(); for(int i=0; i <packageLicenses.length; ++i) { if (line.contains(packageLicenses[i][1])) { packageValidLic.add(packageLicenses[i][0]); Utility.debugPrint(Constants.DEBUG_INFO3, "License for package " + packageLicenses[i][0] + " exists."); } } } Iterator<Map.Entry<String, Boolean>> itPackages = hashMapPackages.entrySet().iterator(); while (itPackages.hasNext()) { Map.Entry<String, Boolean> pairPackage = (Map.Entry<String, Boolean>) itPackages.next(); Iterator<String> itLicPackages = packageValidLic.iterator(); while (itLicPackages.hasNext()) { if(((String)pairPackage.getKey()).startsWith((String)itLicPackages.next())) pairPackage.setValue(Boolean.TRUE); } } itPackages = hashMapPackages.entrySet().iterator(); while (itPackages.hasNext()) { Map.Entry pairPackage = (Map.Entry) itPackages.next(); if(!(Boolean)pairPackage.getValue()) { Utility.debugPrint(Constants.DEBUG_WARNING, "Could not validate license for package " + pairPackage.getKey() + ", please validate manually."); iRetCode = Constants.LIC_NOT_EXIST; } } return iRetCode; } /** * This will return the set of packages from zip file. * * @param zipFileName is the name of zip file from which set of class packages will be returned. * @return Returns set of packages for classes included in the zip file . */ public static HashMap<String, Boolean> getPackagesFromZip (String zipFileName) throws Exception{ HashMap<String, Boolean> packages = new HashMap<String, Boolean>(); try { ZipEntry entry; ZipFile zipfile = new ZipFile(zipFileName); Enumeration e = zipfile.entries(); while(e.hasMoreElements()) { entry = (ZipEntry) e.nextElement(); if(! entry.getName().startsWith(Constants.SYSTEMML_PACKAGE) && entry.getName().endsWith("." + Constants.CLASS)) { int iPos = entry.getName().lastIndexOf("/"); if (iPos > 0) { String strPackageName = entry.getName().substring(0, iPos); packages.put(strPackageName, Boolean.FALSE); Utility.debugPrint(Constants.DEBUG_CODE, "Package found : " + strPackageName); } } } } catch(Exception e) { e.printStackTrace(); throw e; } return packages; } /** * This will return the list of files in licsense files but not in list of files coming from zip/tgz file. * * @param licenseFile is the file against which contents of zip/tgz file gets compared. * @param files are the list of files coming from zip/tgz file. * @param fileExt is the extention of file to validate (e.g. "jar") * @return Returns the list of files in License file but not in zip/tgz file. */ private List<String> getLICENSEFilesNotInList(File licenseFile, List<String> files, String fileExt) throws IOException { List<String> badFiles = new ArrayList<String>(); BufferedReader reader = new BufferedReader(new FileReader(licenseFile)); String line = null; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.contains("." + fileExt)) { StringTokenizer st = new StringTokenizer(line); while (st.hasMoreTokens()) { String s = st.nextToken(); if (s.contains("." + fileExt)) { if (s.startsWith("(")) { s = s.substring(1); } if (s.endsWith(",") || s.endsWith(":")) { s = s.substring(0, s.length()-1); } if (s.endsWith(")")) { s = s.substring(0, s.length()-1); } if (!files.contains(s)) { badFiles.add(s); } } } } } return badFiles; } /** * This will return the list of files in licsense files with specified file extention. * * @param licenseFile is the file against which contents of zip/tgz file gets compared. * @param fileExt is the extention of file to validate (e.g. "jar") * @return Returns the list of files in License file. */ private List<String> getFilesFromLicenseFile(File licenseFile, String fileExt) throws IOException { List<String> files = new ArrayList<String>(); BufferedReader reader = new BufferedReader(new FileReader(licenseFile)); String line = null; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.contains("." + fileExt)) { StringTokenizer st = new StringTokenizer(line); while (st.hasMoreTokens()) { String s = st.nextToken(); if (s.contains("." + fileExt)) { if (s.startsWith("(")) { s = s.substring(1); } if (s.endsWith(",") || s.endsWith(":")) { s = s.substring(0, s.length()-1); } if (s.endsWith(")")) { s = s.substring(0, s.length()-1); } if (!files.contains(s)) { files.add(s); } } } } } return files; } /** * This will return the list of files coming from zip/tgz file but not in the licsense file. * * @param licenseFile is the file against which contents of zip/tgz file gets compared. * @param files are the list of files coming from zip/tgz file. * @param fileExt is the extention of file to validate (e.g. "jar") * @return Returns the list of files in zip/tgz file but not in License file. */ private List<String> getFilesNotInLICENSE(File licenseFile, List<String> files, String fileExt) throws IOException { List<String> badFiles = new ArrayList<String>(); List<String> licFiles = getFilesFromLicenseFile(licenseFile, fileExt); for (String file : files) { if (!licFiles.contains(file)) { badFiles.add(file); } } return badFiles; } /** * This will return the list of zip/tgz files from a directory. * * @param directory is the location from where list of zip/tgz will be returned. * @return Returns the list of zip/tgz files from a directory. */ private List<String> getZipsInDistro(File directory) { List<String> zips = new ArrayList<String>(); for (String fileName : directory.list()) if ((fileName.endsWith("." + Constants.ZIP)) || (fileName.endsWith("." + Constants.TGZ))) zips.add(fileName); return zips; } /** * This will return the content of file. * * @param file is the parameter of type File from which contents will be read and returned. * @return Returns the contents from file in String format. */ private static String readFile(File file) throws java.io.IOException { StringBuffer fileData = new StringBuffer(); BufferedReader reader = new BufferedReader(new FileReader(file)); char[] buf = new char[1024]; int numRead = 0; while ((numRead = reader.read(buf)) != -1) { String readData = String.valueOf(buf, 0, numRead); fileData.append(readData); buf = new char[1024]; } reader.close(); return fileData.toString(); } /** * This will return the file from zip/tgz file and store it in specified location. * * @param zipFileName is the name of zip/tgz file from which file to be extracted. * @param fileName is the name of the file to be extracted. * @param strDestLoc is the location where file will be extracted. * @param bFirstDirLevel to indicate to get file from first directory level. * @return Success or Failure */ public static boolean extractFile(String zipFileName, String fileName, String strDestLoc, boolean bFirstDirLevel) { Utility.debugPrint(Constants.DEBUG_CODE, "Extracting " + fileName + " from jar/zip/tgz file " + zipFileName); if (zipFileName.endsWith("." + Constants.ZIP) || zipFileName.endsWith("." + Constants.JAR)) return extractFileFromZip(zipFileName, fileName, strDestLoc, bFirstDirLevel); else if (zipFileName.endsWith("." + Constants.TGZ)) return extractFileFromTGZ(zipFileName, fileName, strDestLoc, bFirstDirLevel); return Constants.bFAILURE; } /** * This will return the file from zip file and store it in specified location. * * @param zipFileName is the name of zip file from which file to be extracted. * @param fileName is the name of the file to be extracted. * @param strDestLoc is the location where file will be extracted. * @param bFirstDirLevel to indicate to get file from first directory level. * @return Sucess or Failure */ public static boolean extractFileFromZip (String zipFileName, String fileName, String strDestLoc, boolean bFirstDirLevel) { boolean bRetCode = Constants.bFAILURE; try { BufferedOutputStream bufOut = null; BufferedInputStream bufIn = null; ZipEntry entry; ZipFile zipfile = new ZipFile(zipFileName); Enumeration e = zipfile.entries(); while(e.hasMoreElements()) { entry = (ZipEntry) e.nextElement(); if(! entry.getName().endsWith(fileName)) continue; //Get file at root (in single directory) level. This is for License in root location. if( bFirstDirLevel && (entry.getName().indexOf('/') != entry.getName().lastIndexOf('/'))) continue; bufIn = new BufferedInputStream(zipfile.getInputStream(entry)); int count; byte data[] = new byte[Constants.BUFFER]; String strOutFileName = strDestLoc == null ? entry.getName(): strDestLoc + "/" + fileName; FileOutputStream fos = new FileOutputStream(strOutFileName); bufOut = new BufferedOutputStream(fos, Constants.BUFFER); while ((count = bufIn.read(data, 0, Constants.BUFFER)) != -1) { bufOut.write(data, 0, count); } bufOut.flush(); bufOut.close(); bufIn.close(); bRetCode = Constants.bSUCCESS; break; } } catch(Exception e) { e.printStackTrace(); } return bRetCode; } /** * This will return the file from tgz file and store it in specified location. * * @param tgzFileName is the name of tgz file from which file to be extracted. * @param fileName is the name of the file to be extracted. * @param strDestLoc is the location where file will be extracted. * @param bFirstDirLevel to indicate to get file from first directory level. * @return Sucess or Failure */ public static boolean extractFileFromTGZ (String tgzFileName, String fileName, String strDestLoc, boolean bFirstDirLevel) { boolean bRetCode = Constants.bFAILURE; TarArchiveInputStream tarIn = null; try { tarIn = new TarArchiveInputStream( new GzipCompressorInputStream( new BufferedInputStream( new FileInputStream(tgzFileName)))); } catch(Exception e) { Utility.debugPrint(Constants.DEBUG_ERROR, "Exception in unzipping tar file: " + e); return bRetCode; } try { BufferedOutputStream bufOut = null; BufferedInputStream bufIn = null; TarArchiveEntry tarEntry = null; while((tarEntry = tarIn.getNextTarEntry()) != null) { if(! tarEntry.getName().endsWith(fileName)) continue; //Get file at root (in single directory) level. This is for License in root location. if( bFirstDirLevel && (tarEntry.getName().indexOf('/') != tarEntry.getName().lastIndexOf('/'))) continue; bufIn = new BufferedInputStream (tarIn); int count; byte data[] = new byte[Constants.BUFFER]; String strOutFileName = strDestLoc == null ? tarEntry.getName(): strDestLoc + "/" + fileName; FileOutputStream fos = new FileOutputStream(strOutFileName); bufOut = new BufferedOutputStream(fos, Constants.BUFFER); while ((count = bufIn.read(data, 0, Constants.BUFFER)) != -1) { bufOut.write(data, 0, count); } bufOut.flush(); bufOut.close(); bufIn.close(); bRetCode = Constants.bSUCCESS; break; } } catch(Exception e) { e.printStackTrace(); } return bRetCode; } /** * This will return the list of files from zip/tgz file. * * @param zipFileName is the name of zip file from which list of files with specified file extension will be returned. * @param fileExt is the file extension to be used to get list of files to be returned. * @return Returns list of files having specified extention from zip file . */ public static List<String> getFiles (String zipFileName, String fileExt) { if (zipFileName.endsWith("." + Constants.ZIP)) return getFilesFromZip (zipFileName, fileExt); else if (zipFileName.endsWith("." + Constants.TGZ)) return getFilesFromTGZ (zipFileName, fileExt); return null; } /** * This will return the list of files from zip file. * * @param zipFileName is the name of zip file from which list of files with specified file extension will be returned. * @param fileExt is the file extension to be used to get list of files to be returned. * @return Returns list of files having specified extention from zip file . */ public static List<String> getFilesFromZip (String zipFileName, String fileExt) { List<String> files = new ArrayList<String>(); try { ZipEntry entry; ZipFile zipfile = new ZipFile(zipFileName); Enumeration e = zipfile.entries(); while(e.hasMoreElements()) { entry = (ZipEntry) e.nextElement(); if(entry.getName().endsWith("." + fileExt)) { int iPos = entry.getName().lastIndexOf("/"); if (iPos == 0) --iPos; String strFileName = entry.getName().substring(iPos+1); files.add(strFileName); } } } catch(Exception e) { e.printStackTrace(); } return (files); } /** * This will return the list of files from tgz file. * * @param tgzFileName is the name of tgz file from which list of files with specified file extension will be returned. * @param fileExt is the file extension to be used to get list of files to be returned. * @return Returns list of files having specified extention from tgz file . */ public static List<String> getFilesFromTGZ (String tgzFileName, String fileExt) { TarArchiveInputStream tarIn = null; try { tarIn = new TarArchiveInputStream( new GzipCompressorInputStream( new BufferedInputStream( new FileInputStream(tgzFileName)))); } catch(Exception e) { Utility.debugPrint(Constants.DEBUG_ERROR, "Exception in unzipping tar file: " + e); return null; } List<String> files = new ArrayList<String>(); try { TarArchiveEntry tarEntry = null; while((tarEntry = tarIn.getNextTarEntry()) != null) { if(tarEntry.getName().endsWith("." + fileExt)) { int iPos = tarEntry.getName().lastIndexOf("/"); if (iPos == 0) --iPos; String strFileName = tarEntry.getName().substring(iPos+1); files.add(strFileName); } } } catch(Exception e) { e.printStackTrace(); } return (files); } /** * This will return if NOTICE file is valid or not. * * @param noticeFile is the noticew file to be verified. * @return Returns if NOTICE file validatation successful or failure. */ public static boolean validateNotice(String noticeFile) throws Exception { boolean bValidNotice = Constants.bSUCCESS; LocalDateTime currentTime = LocalDateTime.now(); String noticeLines[] = new String[4]; boolean noticeLineIn[] = new boolean[4]; noticeLines[0] = "Apache SystemML"; noticeLines[1] = "Copyright [2015-" + currentTime.getYear() + "] The Apache Software Foundation"; noticeLines[2] = "This product includes software developed at"; noticeLines[3] = "The Apache Software Foundation (http://www.apache.org/)"; BufferedReader reader = new BufferedReader(new FileReader(noticeFile)); String line = null; while ((line = reader.readLine()) != null) { line = line.trim(); for (int i = 0; i < noticeLines.length; i++) { if (line.contains(noticeLines[i])) { noticeLineIn[i] = true; } } } for (int i = 0; i < noticeLines.length; i++) { if (!noticeLineIn[i]) { bValidNotice = Constants.bFAILURE; } } if(bValidNotice == Constants.bSUCCESS) Utility.debugPrint(Constants.DEBUG_INFO2, "Notice validation successful."); return bValidNotice; } /** * This will validate license for JavaScript & CSS files within a zip/tgz file. * * @param licenseFile is the file against which contents of zip/tgz file gets compared. * @param zipFileName is the name of zip/tgz file from which list of JavaScript files will be returned. * @return Success or Failure code */ public static boolean validateJSCssLicense(File licenseFile, String zipFileName) throws Exception { boolean bRetCode = Constants.bSUCCESS; try { List<String> jsFiles = getFiles(zipFileName, Constants.JS); List<String> cssFiles = getFiles(zipFileName, Constants.CSS); HashMap<String, Boolean> jsCssFileHashMap = new HashMap<String, Boolean>(); for (String jsFile : jsFiles) if(jsFile.compareTo("main.js") != 0) jsCssFileHashMap.put(jsFile, Boolean.FALSE); for (String cssFile : cssFiles) if(cssFile.compareTo("main.css") != 0) jsCssFileHashMap.put(cssFile, Boolean.FALSE); BufferedReader reader = new BufferedReader(new FileReader(licenseFile)); String line = null; HashSet<String> packageValidLic = new HashSet<String>(); while ((line = reader.readLine()) != null) { line = line.trim(); //Move to beginning of individual License text if (line.startsWith(Constants.LIC_TEXT_DELIM)) break; } while ((line = reader.readLine()) != null) { line = line.trim(); List<String> curLicense = new ArrayList<String>(); //Read all lines until end of individual License text while (!line.startsWith(Constants.LIC_TEXT_DELIM)) { curLicense.add(line); if ((line = reader.readLine()) == null) break; } //Verify jsFiles against current license foumd. Iterator<Map.Entry<String, String[][]>> itJSLicenses = hmJSLicenses.entrySet().iterator(); while (itJSLicenses.hasNext()) { Map.Entry<String, String[][]> pairJSLicense = (Map.Entry<String, String[][]>) itJSLicenses.next(); String[][] JSLicenseList = pairJSLicense.getValue(); for (String[] license : JSLicenseList) { boolean bLicFirstPartFound = false; for (String licLine : curLicense) { if (!bLicFirstPartFound && licLine.startsWith(license[0])) bLicFirstPartFound = true; if (bLicFirstPartFound && licLine.contains(license[1])) { license[2] = "true"; break; } } } } } //Validate all js/css files against license found in LICENSE file. Iterator<Map.Entry<String, Boolean>> itJSCssFiles = jsCssFileHashMap.entrySet().iterator(); while (itJSCssFiles.hasNext()) { Map.Entry<String, Boolean> pairJSCSSFile = (Map.Entry<String, Boolean>) itJSCssFiles.next(); String[][] jsFileLicList = hmJSLicenses.get(pairJSCSSFile.getKey()); if(jsFileLicList == null) { Utility.debugPrint(Constants.DEBUG_WARNING, "JS/CSS license does not exist for file " + pairJSCSSFile.getKey()); bRetCode = Constants.bFAILURE; continue; } boolean bValidLic = true; for (String[] jsFileLic : jsFileLicList) { if (jsFileLic[2].compareTo("true") != 0) { bValidLic = false; break; } } if (bValidLic) { jsCssFileHashMap.put(pairJSCSSFile.getKey(), Boolean.TRUE); Utility.debugPrint(Constants.DEBUG_INFO3, "JS/CSS license exists for file " + pairJSCSSFile.getKey()); } else { Utility.debugPrint(Constants.DEBUG_WARNING, "JS/CSS license does not exist for file " + pairJSCSSFile.getKey()); bRetCode = Constants.bFAILURE; } } if (bRetCode == Constants.bSUCCESS) Utility.debugPrint(Constants.DEBUG_INFO2, "JS/CSS license validation successful."); } catch (Exception e) { System.out.println(e); e.printStackTrace(); } return bRetCode; } /** * This is main() program. * * @param args is list of arguments * @return */ public static void main(String [] args) { ValidateLicAndNotice valLic; if (args.length > 0) valLic = new ValidateLicAndNotice(args[0]); else valLic = new ValidateLicAndNotice(); try { int retCode = valLic.validate(); Utility.debugPrint(Constants.DEBUG_INFO, "Return code = " + retCode); } catch (Exception e) { Utility.debugPrint(Constants.DEBUG_ERROR, "Error while validating license in zip/tgz file." + e); } } }