forked from spdx/tools-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGenerateVerificationCode.java
More file actions
197 lines (183 loc) · 6.88 KB
/
Copy pathGenerateVerificationCode.java
File metadata and controls
197 lines (183 loc) · 6.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/**
* SPDX-FileCopyrightText: Copyright (c) 2011 Source Auditor Inc.
* SPDX-FileType: SOURCE
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* https://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;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.spdx.core.InvalidSPDXAnalysisException;
import org.spdx.library.model.v2.SpdxPackageVerificationCode;
import org.spdx.storage.IModelStore;
import org.spdx.storage.simple.InMemSpdxStore;
import org.spdx.utility.verificationcode.JavaSha1ChecksumGenerator;
import org.spdx.utility.verificationcode.VerificationCodeGenerator;
/**
* Generates a verification code for a specific directory
* <br/>
* Exit codes:
* <ul>
* <li>0 - the verification code was generated successfully</li>
* <li>1 - the verification code could not be generated</li>
* <li>2 - the command was invoked incorrectly (missing/invalid arguments)</li>
* </ul>
* @author Gary O'Neall
*/
public class GenerateVerificationCode {
/**
* Print an SPDX Verification code for a directory of files
* args[0] is the source directory containing the files
* args[1] is an optional regular expression of skipped files. The expression is applied against a file path relative the the source directory supplied
* Delegates to {@link #run(String[])} and terminates the JVM with its exit status.
* @param args
*/
public static void main(String[] args) {
System.exit(run(args));
}
/**
* Runs the GenerateVerificationCode command logic and reports results to
* standard out.
* @param args
* @return process exit status, see {@link ExitCode}
*/
static int run(String[] args) {
if (args.length < 1 || args.length > 2) {
error("Incorrect number of arguments.");
return ExitCode.USAGE_ERROR;
}
String directoryPath = args[0];
String skippedRegex = null;
if (args.length > 1) {
skippedRegex = args[1];
}
SpdxToolsHelper.initialize();
try {
SpdxPackageVerificationCode verificationCode = generateVerificationCode(directoryPath, skippedRegex);
printVerificationCode(verificationCode);
return ExitCode.SUCCESS;
} catch (Exception ex) {
error("Error creating verification code: "+ex.getMessage());
return ExitCode.ERROR;
}
}
public static SpdxPackageVerificationCode generateVerificationCode(String directoryPath, @Nullable String skippedRegex) throws OnlineToolException {
Objects.requireNonNull(directoryPath, "Directory path must not be null");
File sourceDirectory = new File(directoryPath);
if (!sourceDirectory.exists()) {
throw new OnlineToolException("Source directory "+directoryPath+" does not exist.");
}
if (!sourceDirectory.isDirectory()) {
throw new OnlineToolException("File "+directoryPath+" is not a directory.");
}
File[] skippedFiles = new File[0];
if (Objects.nonNull(skippedRegex)) {
skippedFiles = collectSkippedFiles(skippedRegex, sourceDirectory);
}
try {
VerificationCodeGenerator vcg = new VerificationCodeGenerator(new JavaSha1ChecksumGenerator());
IModelStore ms = new InMemSpdxStore();
return vcg.generatePackageVerificationCode(sourceDirectory, skippedFiles, ms, "https://temp/URI");
} catch (NoSuchAlgorithmException e) {
throw new OnlineToolException("Error creating checksum algorithm",e);
} catch (IOException e) {
throw new OnlineToolException("I/O Error generating verification code",e);
} catch (InvalidSPDXAnalysisException e) {
throw new OnlineToolException("SPDX Analysis Error generating verification code",e);
}
}
/**
* Collect files to be skipped
* @param skippedRegex Regular Expression for file paths to be skipped
* @param dir Directory to scan for collecting skipped files
* @return
*/
private static File[] collectSkippedFiles(String skippedRegex, File dir) {
Pattern skippedPattern = Pattern.compile(skippedRegex);
List<File> skippedFiles = new ArrayList<>();
collectSkippedFiles(skippedPattern, skippedFiles, dir.getPath(), dir);
File[] retval = new File[skippedFiles.size()];
retval = skippedFiles.toArray(retval);
return retval;
}
/**
* Internal method to recurse through the source directory collecting files to skip
* @param skippedPattern
* @param skippedFiles
* @param rootPath
* @param dir
* @return
*/
private static void collectSkippedFiles(Pattern skippedPattern,
List<File> skippedFiles, String rootPath, File dir) {
if (dir.isFile()) {
String relativePath = dir.getPath().substring(rootPath.length()+1);
if (skippedPattern.matcher(relativePath).matches()) {
skippedFiles.add(dir);
}
} else if (dir.isDirectory()) {
File[] children = dir.listFiles();
if (children != null) {
for (int i = 0; i < children.length; i++) {
if (children[i].isFile()) {
String relativePath = children[i].getPath().substring(rootPath.length()+1);
if (skippedPattern.matcher(relativePath).matches()) {
skippedFiles.add(children[i]);
}
} else if (children[i].isDirectory()) {
collectSkippedFiles(skippedPattern, skippedFiles, rootPath, children[i]);
}
}
}
}
}
/**
* @param verificationCode
* @throws InvalidSPDXAnalysisException
*/
private static void printVerificationCode(
SpdxPackageVerificationCode verificationCode) throws InvalidSPDXAnalysisException {
System.out.println("Verification code value: "+verificationCode.getValue());
String[] excludedFiles = verificationCode.getExcludedFileNames().toArray(new String[verificationCode.getExcludedFileNames().size()]);
if (excludedFiles != null && excludedFiles.length > 0) {
System.out.println("Excluded files:");
for (int i = 0; i < excludedFiles.length; i++) {
System.out.println("\t"+excludedFiles[i]);
}
} else {
System.out.println("No excluded files");
}
}
/**
* @param string
*/
private static void error(String string) {
System.out.println(string);
usage();
}
/**
*
*/
private static void usage() {
System.out.println("Usage: GenerateVerificationCode sourceDirectory [skippedFiles]");
System.out.println("where sourceDirectory is the root of the archive file for which the verification code is generated and [skippedFiles] is an optional regular expression of skipped files. The expression is applied against a file path relative the the source directory supplied");
}
}