All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.spdx.tools.compare.MultiDocumentSpreadsheet Maven / Gradle / Ivy

There is a newer version: 2.0.0-Alpha
Show newest version
/**
 * Copyright (c) 2013 Source Auditor Inc.
 * Copyright (c) 2013 Black Duck Software Inc.
 *
 *   Licensed 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.spdx.tools.compare;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spdx.library.InvalidSPDXAnalysisException;
import org.spdx.library.model.SpdxFile;
import org.spdx.spreadsheetstore.SpreadsheetException;
import org.spdx.utility.compare.SpdxCompareException;
import org.spdx.utility.compare.SpdxComparer;

/**
 * Spreadsheet holding the results of a comparison from multiple SPDX documents
 * Each sheet contains the comparison result results with the columns representing the SPDX documents
 * and the rows representing the SPDX fields.
 *
 * The sheets include:
 *   - document: Document level fields Created, Data License, Document Comment, created date, creator comment
 *   - creator: Creators
 *   - package: Package level fields name, version, filename, supplier, ...
 *   - extracted license info: Extracted license text and identifiers
 *   - file checksums: file checksums
 *   - file concluded: license concluded for each file
 *   - file licenseInfo: license information from each file
 *   - file license comments: license comments from each file
 *   - file artifactOfs: artifact of for all files
 *   - file type: file type of all files
 *   - reviewers: review information
 *   - verification: List of any verification errors
 *
 * @author Gary O'Neall
 *
 */
public class MultiDocumentSpreadsheet {

	protected static final class SpdxFileComparator implements Comparator {

		private NormalizedFileNameComparator normalizedFileNameComparator = new NormalizedFileNameComparator();

		/* (non-Javadoc)
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		@Override
		public int compare(SpdxFile arg0, SpdxFile arg1) {
			try {
				return normalizedFileNameComparator.compare(arg0.getName(), arg1.getName());
			} catch (InvalidSPDXAnalysisException e) {
				logger.error("Error getting SPDX file names",e);
				throw new RuntimeException(e);
			}
		}
	}

	protected File saveFile;
	protected Workbook workbook;

	private boolean readonly;
	private SpdxFileComparator fileComparator = new SpdxFileComparator();

	static Logger logger = LoggerFactory.getLogger(MultiDocumentSpreadsheet.class);
	protected static final String DOCUMENT_SHEET_NAME = "Document";
	protected DocumentSheet documentSheet;
	protected static final String CREATOR_SHEET_NAME = "Creator";
	protected CreatorSheet creatorSheet;
	protected static final String PACKAGE_SHEET_NAME = "Package";
	protected PackageSheet packageSheet;
	protected static final String EXTRACTED_LICENSE_SHEET_NAME = "Extracted Licenses";
	protected ExtractedLicenseSheet extractedLicenseSheet;
	protected static final String FILE_CHECKSUM_SHEET_NAME = "File Checksum";
	protected FileChecksumSheet fileChecksumSheet;
	protected static final String FILE_CONCLUDED_SHEET_NAME = "File Concluded";
	protected FileConcludedSheet fileConcludedSheet;
	protected static final String FILE_FOUND_SHEET_NAME = "File Found Licenses";
	protected FileLicenseInfoSheet fileLicenseInfoSheet;
	protected static final String FILE_LICENSE_COMMENT_SHEET_NAME = "File License Comment";
	protected FileLicenseCommentsSheet fileLicenseCommentsSheet;
	protected static final String FILE_COMMENT_SHEET_NAME = "File Comment";
	protected FileCommentSheet fileCommentSheet;
	protected static final String FILE_TYPE_SHEET_NAME = "File Type";
	protected FileTypeSheet fileTypeSheet;
	protected static final String FILE_CONTRIBUTOR_SHEET_NAME = "File Contributors";
	protected FileContributorsSheet fileContributorsSheet;
	protected static final String FILE_ATTRIBUTION_SHEET_NAME = "File Attribution";
	protected FileAttributionSheet fileAttributionSheet;
	protected static final String FILE_NOTICE_SHEET_NAME = "File Notices";
	protected FileNoticeSheet fileNoticeSheet;
	protected static final String VERIFICATION_SHEET_NAME = "Verification Errors";
	public static final int MAX_DOCUMENTS = 25;
	protected static final String EXTERNAL_REFERENCES_SHEET_NAME = "Ext. Doc. References";
	protected static final String DOCUMENT_RELATIONSHIP_SHEET_NAME = "Doc. Relationships";
	protected static final String DOCUMENT_ANNOTATION_SHEET_NAME = "Doc. Annotations";
	protected static final String FILE_SPDX_ID_SHEET_NAME = "File IDs";
	protected static final String FILE_COPYRIGHT_SHEET_NAME = "File Copyrights";
	protected static final String FILE_ANNOTATION_SHEET_NAME = "File Annot.";
	protected static final String FILE_RELATIONSHIP_SHEET = "File Relationships";
	protected static final String SNIPPET_SHEET_NAME = "Snippets";

	protected VerificationSheet verificationSheet;

	protected ExternalReferencesSheet externalReferencesSheet;

	protected DocumentAnnotationSheet documentAnnotationSheet;

	protected DocumentRelationshipSheet documentRelationshipSheet;

	protected FileSpdxIdSheet fileSpdxIdSheet;

	protected FileCopyrightSheet fileCopyrightSheet;

	protected FileAnnotationSheet fileAnnotationSheet;

	protected FileRelationshipSheet fileRelationshipSheet;

	protected SnippetSheet snippetSheet;

	/**
	 * @param spreadsheetFile
	 * @param create
	 * @param readonly
	 * @throws SpreadsheetException
	 */
	public MultiDocumentSpreadsheet(File spreadsheetFile, boolean create,
			boolean readonly) throws SpreadsheetException {
		this.readonly = readonly;
		if (readonly && create) {
			throw(new SpreadsheetException("Can not create a readonly spreadsheet"));
		}
		if (!spreadsheetFile.exists()) {
			if (!create) {
				throw(new SpreadsheetException("File "+spreadsheetFile.getName()+" does not exist"));
			}
			try {
				create(spreadsheetFile);
			} catch (IOException ex) {
				logger.error("IO error creating spreadsheet: "+ex.getMessage());
				throw(new SpreadsheetException("I/O error creating spreadsheet"));
			}
		}
		this.saveFile = spreadsheetFile;
		InputStream input = null;
		try {
			input = new FileInputStream(spreadsheetFile);
			workbook = WorkbookFactory.create(input);
		} catch (FileNotFoundException ex) {
			logger.error("Can not open Excel file.  File "+
					spreadsheetFile.getName()+" does not exist");
			throw(new SpreadsheetException("Can not open Excel file.  File "+
					spreadsheetFile.getName()+" does not exist"));
		} catch (IOException ex) {
			logger.error("IO Exception opening excel workbook: "+ex.getMessage());
			throw(new SpreadsheetException("IO Exception opening excel workbook.  See log for more detail."));
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException ex) {
					logger.warn("IO Error closing excel file: "+ex.getMessage());
				}
			}
		}
		documentSheet = new DocumentSheet(this.workbook, DOCUMENT_SHEET_NAME);
		externalReferencesSheet = new ExternalReferencesSheet(this.workbook, EXTERNAL_REFERENCES_SHEET_NAME);
		creatorSheet = new CreatorSheet(this.workbook, CREATOR_SHEET_NAME);
		documentAnnotationSheet = new DocumentAnnotationSheet(this.workbook, DOCUMENT_ANNOTATION_SHEET_NAME);
		documentRelationshipSheet = new DocumentRelationshipSheet(this.workbook, DOCUMENT_RELATIONSHIP_SHEET_NAME);
		packageSheet = new PackageSheet(this.workbook, PACKAGE_SHEET_NAME);
		extractedLicenseSheet = new ExtractedLicenseSheet(this.workbook, EXTRACTED_LICENSE_SHEET_NAME);
		fileSpdxIdSheet = new FileSpdxIdSheet(this.workbook, FILE_SPDX_ID_SHEET_NAME);
		fileTypeSheet = new FileTypeSheet(this.workbook, FILE_TYPE_SHEET_NAME);
		fileChecksumSheet = new FileChecksumSheet(this.workbook, FILE_CHECKSUM_SHEET_NAME);
		fileConcludedSheet = new FileConcludedSheet(this.workbook, FILE_CONCLUDED_SHEET_NAME);
		fileLicenseInfoSheet = new FileLicenseInfoSheet(this.workbook, FILE_FOUND_SHEET_NAME);
		fileLicenseCommentsSheet = new FileLicenseCommentsSheet(this.workbook, FILE_LICENSE_COMMENT_SHEET_NAME);
		fileCopyrightSheet = new FileCopyrightSheet(this.workbook, FILE_COPYRIGHT_SHEET_NAME);
		fileCommentSheet = new FileCommentSheet(this.workbook, FILE_COMMENT_SHEET_NAME);
		fileNoticeSheet = new FileNoticeSheet(this.workbook, FILE_NOTICE_SHEET_NAME);
		fileContributorsSheet = new FileContributorsSheet(this.workbook, FILE_CONTRIBUTOR_SHEET_NAME);
		fileAttributionSheet = new FileAttributionSheet(this.workbook, FILE_ATTRIBUTION_SHEET_NAME);
		fileAnnotationSheet = new FileAnnotationSheet(this.workbook, FILE_ANNOTATION_SHEET_NAME);
		fileRelationshipSheet = new FileRelationshipSheet(this.workbook, FILE_RELATIONSHIP_SHEET);
		snippetSheet = new SnippetSheet(this.workbook, SNIPPET_SHEET_NAME);
		verificationSheet = new VerificationSheet(this.workbook, VERIFICATION_SHEET_NAME);
		String verify = this.verifyWorkbook();
		if (verify != null && !verify.isEmpty()) {
			logger.error("Invalid workbook: "+verify);
			throw(new SpreadsheetException("Invalid workbook: "+verify));
		}
	}

	/* (non-Javadoc)
	 * @see org.spdx.spdxspreadsheet.AbstractSpreadsheet#create(java.io.File)
	 */
	public void create(File spreadsheetFile) throws IOException, SpreadsheetException {
		if (!spreadsheetFile.createNewFile()) {
			logger.error("Unable to create "+spreadsheetFile.getName());
			throw(new SpreadsheetException("Unable to create "+spreadsheetFile.getName()));
		}
		FileOutputStream excelOut = null;
		try {
			excelOut = new FileOutputStream(spreadsheetFile);
			Workbook wb = new XSSFWorkbook();
			DocumentSheet.create(wb, DOCUMENT_SHEET_NAME);
			CreatorSheet.create(wb, CREATOR_SHEET_NAME);
			ExternalReferencesSheet.create(wb, EXTERNAL_REFERENCES_SHEET_NAME);
			DocumentAnnotationSheet.create(wb, DOCUMENT_ANNOTATION_SHEET_NAME);
			DocumentRelationshipSheet.create(wb, DOCUMENT_RELATIONSHIP_SHEET_NAME);
			PackageSheet.create(wb, PACKAGE_SHEET_NAME);
			ExtractedLicenseSheet.create(wb, EXTRACTED_LICENSE_SHEET_NAME);
			FileSpdxIdSheet.create(wb, FILE_SPDX_ID_SHEET_NAME);
			FileChecksumSheet.create(wb, FILE_CHECKSUM_SHEET_NAME);
			FileConcludedSheet.create(wb, FILE_CONCLUDED_SHEET_NAME);
			FileLicenseInfoSheet.create(wb, FILE_FOUND_SHEET_NAME);
			FileCommentSheet.create(wb, FILE_COMMENT_SHEET_NAME);
			FileCopyrightSheet.create(wb, FILE_COPYRIGHT_SHEET_NAME);
			FileLicenseCommentsSheet.create(wb, FILE_LICENSE_COMMENT_SHEET_NAME);
			FileTypeSheet.create(wb, FILE_TYPE_SHEET_NAME);
			FileContributorsSheet.create(wb, FILE_CONTRIBUTOR_SHEET_NAME);
			FileAttributionSheet.create(wb, FILE_ATTRIBUTION_SHEET_NAME);
			FileNoticeSheet.create(wb, FILE_NOTICE_SHEET_NAME);
			FileAnnotationSheet.create(wb, FILE_ANNOTATION_SHEET_NAME);
			FileRelationshipSheet.create(wb, FILE_RELATIONSHIP_SHEET);
			SnippetSheet.create(wb, SNIPPET_SHEET_NAME);
			VerificationSheet.create(wb, VERIFICATION_SHEET_NAME);
			wb.write(excelOut);
		} finally {
		    if(excelOut != null){
		        excelOut.close();
		    }
		}
	}

	public void importCompareResults(SpdxComparer comparer, List docNames) throws SpdxCompareException, InvalidSPDXAnalysisException {
		if (docNames == null) {
			throw(new SpdxCompareException("Doc names can not be null"));
		}
		if (comparer == null) {
			throw(new SpdxCompareException("Comparer names can not be null"));
		}
		if (docNames.size() != comparer.getNumSpdxDocs()) {
			throw(new SpdxCompareException("Number of document names does not match the number of documents compared"));
		}

		List> files = new ArrayList<>();
		for (int i = 0; i < comparer.getNumSpdxDocs(); i++) {
			List docFiles = comparer.collectAllFiles(comparer.getSpdxDoc(i));
			Collections.sort(docFiles, fileComparator);
			files.add(docFiles);
		}
		documentSheet.importCompareResults(comparer, docNames);
		documentSheet.resizeRows();
		creatorSheet.importCompareResults(comparer, docNames);
		creatorSheet.resizeRows();
		externalReferencesSheet.importCompareResults(comparer, docNames);
		externalReferencesSheet.resizeRows();
		documentAnnotationSheet.importCompareResults(comparer, docNames);
		documentAnnotationSheet.resizeRows();
		documentRelationshipSheet.importCompareResults(comparer, docNames);
		documentRelationshipSheet.resizeRows();
		packageSheet.importCompareResults(comparer, docNames);
		packageSheet.resizeRows();
		fileSpdxIdSheet.importCompareResults(comparer, files, docNames);
		fileSpdxIdSheet.resizeRows();
		extractedLicenseSheet.importCompareResults(comparer, docNames);
		extractedLicenseSheet.resizeRows();
		fileChecksumSheet.importCompareResults(comparer, files, docNames);
		fileChecksumSheet.resizeRows();
		fileConcludedSheet.importCompareResults(comparer, files, docNames);
		fileConcludedSheet.resizeRows();
		fileLicenseInfoSheet.importCompareResults(comparer, files, docNames);
		fileLicenseInfoSheet.resizeRows();
		fileCopyrightSheet.importCompareResults(comparer, files, docNames);
		fileCopyrightSheet.resizeRows();
		fileCommentSheet.importCompareResults(comparer, files, docNames);
		fileCommentSheet.resizeRows();
		fileLicenseCommentsSheet.importCompareResults(comparer, files, docNames);
		fileLicenseCommentsSheet.resizeRows();
		fileTypeSheet.importCompareResults(comparer, files, docNames);
		fileTypeSheet.resizeRows();
		fileContributorsSheet.importCompareResults(comparer, files, docNames);
		fileContributorsSheet.resizeRows();
		fileAttributionSheet.importCompareResults(comparer, files, docNames);
		fileAttributionSheet.resizeRows();
		fileNoticeSheet.importCompareResults(comparer, files, docNames);
		fileNoticeSheet.resizeRows();
		fileAnnotationSheet.importCompareResults(comparer, files, docNames);
		fileAnnotationSheet.resizeRows();
		fileRelationshipSheet.importCompareResults(comparer, files, docNames);
		fileRelationshipSheet.resizeRows();
		snippetSheet.importCompareResults(comparer, docNames);
		snippetSheet.resizeRows();
	}

	public void clear() {
		documentSheet.clear();
		creatorSheet.clear();
		packageSheet.clear();
		extractedLicenseSheet.clear();
		fileChecksumSheet.clear();
		fileConcludedSheet.clear();
		fileLicenseInfoSheet.clear();
		fileLicenseCommentsSheet.clear();
		verificationSheet.clear();
		fileCommentSheet.clear();
		fileContributorsSheet.clear();
		fileAttributionSheet.clear();
		fileNoticeSheet.clear();
		snippetSheet.clear();
	}

	public String verifyWorkbook() {
		StringBuilder sb = new StringBuilder();
		String sheetVerify = documentSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append(sheetVerify);
		}
		sheetVerify = creatorSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = packageSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = extractedLicenseSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = fileChecksumSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = fileConcludedSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = fileLicenseInfoSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = fileCommentSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = fileLicenseCommentsSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = fileContributorsSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = fileAttributionSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = fileNoticeSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = verificationSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		sheetVerify = snippetSheet.verify();
		if (sheetVerify != null && !sheetVerify.isEmpty()) {
			sb.append("; ");
			sb.append(sheetVerify);
		}
		if (sb.length() > 0) {
			return sb.toString();
		} else {
			return null;
		}
	}

	/**
	 * @param verificationErrors
	 * @param docNames
	 * @throws SpreadsheetException
	 */
	public void importVerificationErrors(
			List> verificationErrors, List docNames) throws SpreadsheetException {
		this.verificationSheet.importVerificationErrors(verificationErrors, docNames);
		this.verificationSheet.resizeRows();
	}
	
	/**
	 * @throws AnalyzeException
	 *
	 */
	public void close() throws SpreadsheetException {
		try {
			writeToFile(this.saveFile);
		} catch (IOException ex) {
			logger.error("Error writing excel sheet to file: "+ex.getMessage());
			throw(new SpreadsheetException("Error writing excel workbook to file, see log for details."));
		}
	}
	
	/**
	 * Writes the spreadsheet to a file
	 * @throws IOException
	 */
	public void writeToFile(File file) throws IOException {
		if (readonly) {
			return;
		}
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(file);
			this.workbook.write(out);
		} finally {
			if (out != null) {
				out.close();
			}
		}

	}

	public DocumentSheet getDocumentSheet() {
		return this.documentSheet;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy