| /* |
| * 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.sysds.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/systemds/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"}, |
| {"caffe","The proto file (src/main/proto/caffe/caffe.proto) is part of Caffe project,"}, |
| {"org/tensorflow","The proto files (src/main/proto/tensorflow/event.proto and src/main/proto/tensorflow/summary.proto) is part of TensorFlow project,"}, |
| {"jcuda","JCuda (jcuda.org)"}, |
| }; |
| |
| 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 archives 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 archives 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 archive: " + 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> fileSysds = new ArrayList<String>(); |
| for (String file : filesAll) { |
| int sysdsLen = Constants.SYSTEMDS_NAME.length(); |
| String strBegPart = file.substring(0, sysdsLen); |
| if (strBegPart.compareToIgnoreCase(Constants.SYSTEMDS_NAME) != 0) |
| files.add(file); |
| else |
| fileSysds.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 archive. |
| if(fileType == Constants.JAR) { |
| for (String file : fileSysds) |
| retCode += ValidateLicAndNotice.validateShadedLic(libDirectory + "/" + zipFile, file, outTempDir.getAbsolutePath()); |
| if (!validateNotice(outTempDir.getAbsolutePath()+"/"+Constants.NOTICE)) { |
| Utility.debugPrint(Constants.DEBUG_ERROR, "Notice validation failed, please check notice file manually in this archive."); |
| retCode += Constants.INVALID_NOTICE; |
| } |
| if (!validateJSCssLicense(licenseFile, libDirectory + "/" + zipFile)) { |
| Utility.debugPrint(Constants.DEBUG_ERROR, "JS/CSS license validation failed, please check license file manually in this archive."); |
| retCode += Constants.JS_CSS_LIC_NOT_EXIST; |
| } |
| } |
| |
| if (retCode == Constants.SUCCESS) |
| Utility.debugPrint(Constants.DEBUG_INFO3, "Validation of file type '." + fileType + "' in archive " + zipFile + " completed successfully."); |
| else { |
| Utility.debugPrint(Constants.DEBUG_ERROR, "License/Notice validation failed for archive " + zipFile + " with error code " + retCode + ", please validate file manually."); |
| retCodeForAllFileTypes = Constants.FAILURE; |
| } |
| } |
| if(retCodeForAllFileTypes == Constants.SUCCESS) |
| Utility.debugPrint(Constants.DEBUG_INFO, "Validation of archive " + 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.SYSTEMDS_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 license files but not in list of files coming from archive. |
| * |
| * @param licenseFile is the file against which contents of archive gets compared. |
| * @param files are the list of files coming from archive. |
| * @param fileExt is the extension of file to validate (e.g. "jar") |
| * @return Returns the list of files in License file but not in archive. |
| */ |
| 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 license files with specified file extension. |
| * |
| * @param licenseFile is the file against which contents of archive gets compared. |
| * @param fileExt is the extension 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 archive but not in the license file. |
| * |
| * @param licenseFile is the file against which contents of archive gets compared. |
| * @param files are the list of files coming from archive. |
| * @param fileExt is the extension of file to validate (e.g. "jar") |
| * @return Returns the list of files in archive 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 archives from a directory. |
| * |
| * @param directory is the location from where list of archives will be returned. |
| * @return Returns the list of archives (e.g., .zip/tgz/tar.gz 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)) || |
| (fileName.endsWith("." + Constants.TAR_GZ))) { |
| 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 archive and store it in specified location. |
| * |
| * @param zipFileName is the name of archive 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 archive " + zipFileName); |
| if (zipFileName.endsWith("." + Constants.ZIP) || zipFileName.endsWith("." + Constants.JAR)) |
| return extractFileFromZip(zipFileName, fileName, strDestLoc, bFirstDirLevel); |
| else if (zipFileName.endsWith("." + Constants.TGZ) || zipFileName.endsWith("." + Constants.TAR_GZ)) |
| 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 archive. |
| * |
| * @param zipFileName is the name of archive (e.g., .zip/tgz/tar.gz 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 extension from archive. |
| */ |
| public static List<String> getFiles (String zipFileName, String fileExt) { |
| if (zipFileName.endsWith("." + Constants.ZIP)) |
| return getFilesFromZip (zipFileName, fileExt); |
| else if (zipFileName.endsWith("." + Constants.TGZ) || zipFileName.endsWith("." + Constants.TAR_GZ)) |
| 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 extension 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 extension 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[2]; |
| boolean noticeLineIn[] = new boolean[4]; |
| |
| // ToDo: fix notice lines |
| noticeLines[0] = "Apache SystemDS"; |
| noticeLines[1] = "Copyright [2015-" + currentTime.getYear() + "]"; |
| |
| 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 an archive. |
| * |
| * @param licenseFile is the file against which contents of archive gets compared. |
| * @param zipFileName is the name of archive 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 archive: " + e); |
| } |
| } |
| |
| } |