You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2009/04/08 14:30:29 UTC
svn commit: r763213 [2/2] - in /felix/sandbox/clement/Project-Checker: ./
.settings/ libs/ licenses/ src/ src/org/ src/org/apache/
src/org/apache/felix/ src/org/apache/felix/project/
src/org/apache/felix/project/checker/
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Project.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Project.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Project.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Project.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,519 @@
+package org.apache.felix.project.checker;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+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.io.StringReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import javax.swing.text.html.parser.ParserDelegator;
+
+public class Project {
+
+ public static final String CONFIG_FILE= "config.properties";
+
+ private static final String LICENSE_REPOSITORY = "licenses";
+
+ private static final int PROJECT_MODE = 0;
+ private static final int RELEASE_MODE = 1;
+
+ public static final String UNZIP_PROPERTY = "UNZIP";
+
+ private URL url;
+ private String name;
+ private String version;
+ private File directory;
+
+ private Properties props;
+
+ private Map<String, File> artifacts = new HashMap<String, File>();
+
+ private Notice notice;
+
+ private Date downloadDate;
+
+ private List<Checker> checkers = new ArrayList<Checker>();
+
+ private List<Checker> success = new ArrayList<Checker>();
+
+ private List<Checker> skipped = new ArrayList<Checker>();
+
+ private Map<Checker, List<String>> warning = new HashMap<Checker, List<String>>();
+
+ private Map<Checker, List<String>> error = new HashMap<Checker, List<String>>();
+
+ private List<License> licences;
+
+ private int mode;
+
+ private File root;
+
+ private JarFile jar;
+
+ public Project(String url, String name, String version, boolean project_mode) throws FileNotFoundException, IOException {
+ this(url, name, version, CONFIG_FILE, project_mode);
+ }
+
+ public Project(String url, String name, String version, String configuration, boolean project_mode) throws FileNotFoundException, IOException {
+ if (project_mode) {
+ mode = PROJECT_MODE;
+ } else {
+ mode = RELEASE_MODE;
+ }
+
+ // Load configuration.
+ props = new Properties();
+ props.load(new FileInputStream(new File(configuration)));
+
+
+ // Set project name and version
+ this.name = name;
+ this.version = version;
+
+ assert(this.name != null);
+ assert(this.version != null);
+
+ checkers = new ArrayList<Checker>();
+
+ // Add default checkers.
+ checkers.add(new ProjectLicenseChecker());
+ checkers.add(new ProjectNoticeChecker());
+ checkers.add(new JarNoticeChecker());
+ checkers.add(new JarLicenseChecker());
+ checkers.add(new HeaderChecker());
+ checkers.add(new LicenseSummaryChecker());
+ checkers.add(new NoticeNameChecker());
+ checkers.add(new NoticeCopyrightChecker());
+ checkers.add(new IncludedApacheLicence());
+ checkers.add(new IncludedLicenseChecker());
+ checkers.add(new UsedLicenseChecker());
+
+
+ // if release mode, create the temporary directory
+ if (mode == RELEASE_MODE) {
+ directory = new File("release-" + name + "-" + version);
+ this.url = new URL(url);
+
+ checkers.add(new FileChecker());
+ checkers.add(new SignatureBeautifiedChecker());
+ checkers.add(new SignatureChecker());
+ checkers.add(new MD5Checker());
+ checkers.add(new Sha1Checker());
+ checkers.add(new ChangelogChecker());
+ checkers.add(new TagChecker());
+ } else {
+ root = new File(url);
+ directory = new File(root, "target");
+ }
+ }
+
+ public Notice getNotice() {
+ return notice;
+ }
+
+ public String getProperty(String name) {
+ return props.getProperty(name);
+ }
+
+ public List<License> getKnownLicense() {
+ return licences;
+ }
+
+ public void download() throws Exception {
+ Map<String, URL> urls = getURLs();
+
+
+ directory.mkdir();
+ Iterator<String> it = urls.keySet().iterator();
+
+ while(it.hasNext()) {
+ String name = it.next();
+ URL url = urls.get(name);
+
+ System.out.println("Downloading " + name);
+ downloadDate = new Date();
+
+ File file = new File(directory, name);
+ directory.mkdirs();
+ FileOutputStream writer = new FileOutputStream(file);
+ InputStream is = url.openStream();
+ int cc = 0;
+ do {
+ int i = is.read();
+ if (i == -1)
+ break;
+ cc++;
+ writer.write(i);
+ } while (true);
+
+ is.close();
+ writer.close();
+
+ System.out.println(name + " downloaded");
+
+ }
+
+ }
+
+ private void prepareProjectMode() throws Exception {
+ // Check that the root as a pom files, and the jar file exists.
+ File pom = new File(root, "pom.xml");
+ if (! pom.exists()) {
+ throw new Exception("No pom file in the directory " + root.getAbsolutePath());
+ }
+
+ File jarF = new File(root, "target/" + name + "-" + version + ".jar");
+ System.out.println(jarF.getAbsolutePath());
+ if (! jarF.exists()) {
+ throw new Exception("No jar file in the target directory");
+ }
+
+ jar = new JarFile(jarF);
+
+ artifacts.put(jarF.getName(), jarF);
+
+ }
+
+ private void prepareReleaseMode() throws Exception {
+ // Compute the project artifacts
+ File[] files = getArtifactDirectory().listFiles();
+ for (int i = 0; i < files.length; i++) {
+ artifacts.put(files[i].getName(), files[i]);
+ }
+
+ // Get the Jar file
+ // Extract the notice and parse it.
+ Iterator<String> it = artifacts.keySet().iterator();
+ File project = null;
+ while(it.hasNext()) {
+ String f = it.next();
+ if (f.endsWith(getVersion() + ".jar")) { // Avoid sources.
+ jar = new JarFile(artifacts.get(f));
+ }
+ if (f.endsWith(getVersion() + "-project.zip")) {
+ project = artifacts.get(f);
+ }
+ }
+
+ if (jar == null) {
+ throw new Exception("Cannot prepare the checking : No Jar file !");
+ }
+
+ if (project == null) {
+ throw new Exception("Cannot prepare the checking : No project file !");
+ }
+
+ // Unzip the project file
+ Command cmd = new Command();
+ cmd.executeCommand(this, getProperty(UNZIP_PROPERTY) + " -u " + project.getName(), false);
+
+ root = new File(directory, name + "-" + version);
+ if (! root.exists()) {
+ throw new Exception("Cannot prepare the checking : Project cannot be unzipped !");
+ }
+
+
+
+ }
+
+ public void prepareChecking() throws Exception {
+ File repo = new File(LICENSE_REPOSITORY);
+ licences = LicenseParser.getKnownLicenses(repo);
+
+ if (mode == PROJECT_MODE) {
+ prepareProjectMode();
+ } else {
+ prepareReleaseMode();
+ }
+
+ // Get notice
+ ZipEntry ze = jar.getEntry("META-INF/NOTICE");
+ InputStream is = jar.getInputStream(ze);
+ File not = new File(getArtifactDirectory(), "NOTICE");
+ FileOutputStream os = new FileOutputStream(not);
+ int c;
+ int i = 0;
+ while ((c = is.read()) >= 0) {
+ os.write(c);
+ i++;
+ }
+ is.close();
+
+ notice = new Notice(not);
+
+ }
+
+ private Map<String, URL> getURLs() throws Exception {
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ System.out.println("Opening stream " + url);
+
+ InputStream is = connection.getInputStream();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ int cc = 0;
+ do {
+ int i = is.read();
+ if (i == -1)
+ break;
+ cc++;
+ bos.write(i);
+ } while (true);
+
+
+ byte[] bytes = bos.toByteArray();
+
+ try {
+ bos.close();
+ is.close();
+ connection.disconnect();
+ } catch (Exception e) {
+ throw new Exception("Cannot get urls : " + e.getMessage());
+ }
+
+ return computeURLs(bytes);
+ }
+
+ private Map<String, URL> computeURLs(byte[] stream) throws IOException {
+ try {
+ BufferedReader reader = new BufferedReader(new StringReader(new String(stream)));
+ LinkCollector lk = new LinkCollector(url, name);
+ new ParserDelegator().parse(reader,lk, true);
+ return lk.getlist();
+ }
+ catch (IOException ioe) {
+ System.out.println("IOE: " + ioe);
+ }
+ return null;
+
+ }
+
+ public File getProjectRoot() {
+ assert root.exists();
+ return root;
+ }
+
+ public JarFile getJar() {
+ assert jar != null;
+ return jar;
+ }
+
+ public void check() throws Exception {
+ for (Checker chk : checkers) {
+ boolean ok = chk.prepare(this);
+ if (ok) {
+ try {
+ chk.check();
+ chk.clean();
+ if (! error.containsKey(chk)) {
+ success(chk);
+ }
+ } catch (Exception e) {
+ if (e.getCause() != null) {
+ error(chk, e.getMessage(), e.getCause().getMessage());
+ } else {
+ error(chk, e.getMessage(), null);
+ }
+ }
+ } else {
+ skipped.add(chk);
+ }
+ }
+ printReport();
+ }
+
+ public void error(Checker chk, String error, String cause) {
+ List<String> list = this.error.get(chk);
+ if (list == null) {
+ list = new ArrayList<String>();
+ this.error.put(chk, list);
+ }
+ if (cause != null) {
+ String err = error + ":\n" + cause;
+ list.add(err);
+ } else {
+ list.add(error);
+ }
+ }
+
+ public void warning(Checker chk, String message) {
+ List<String> list = this.warning.get(chk);
+ if (list == null) {
+ list = new ArrayList<String>();
+ this.warning.put(chk, list);
+ }
+ list.add(message);
+ }
+
+ private void success(Checker chk) {
+ success.add(chk);
+ }
+
+ public static void main(String[] args) throws Exception {
+ String url = null;
+ String name = null;
+ String version = null;
+ String configuration = null;
+ boolean download = true;
+ boolean project = false;
+ for (int i = 0; i < args.length; i++) {
+ if (! args[i].contains("-")) {
+ continue; // Skip the value.
+ }
+ if (args[i].equals("-u") || args[i].equals("--url")) {
+ url = args[i+1];
+ project = false;
+ }
+ if (args[i].equals("-n") || args[i].equals("--name")) {
+ name = args[i+1];
+ }
+ if (args[i].equals("-v") || args[i].equals("--version")) {
+ version = args[i+1];
+ }
+ if (args[i].equals("-c") || args[i].equals("--config")) {
+ configuration = args[i+1];
+ }
+ if (args[i].equals("-o") || args[i].equals("--offline")) {
+ download = false;
+ }
+ if (args[i].equals("-d") || args[i].equals("--directory")) {
+ url = args[i+1];
+ project = true;
+ }
+ }
+
+ if (url == null || name == null || version == null) {
+ printUsage();
+ return;
+ }
+ Project release = null;
+ if (configuration == null) {
+ release = new Project(url, name, version, project);
+ } else {
+ release = new Project(url, name, version, configuration, project);
+ }
+
+ if (! project && download) {
+ release.download();
+ }
+
+ release.prepareChecking();
+ release.check();
+ release.clean();
+
+
+ // Release release = new Release("http://people.apache.org/~pauls/1.6.0/", "org.apache.felix.bundlerepository", "1.4.0");
+ // Release release = new Release("http://people.apache.org/~clement/releases/org/apache/felix/org.apache.felix.http.jetty/1.0.0/", "org.apache.felix.http.jetty", "1.0.0");
+ // release.download();
+ }
+
+ private static void printUsage() {
+ StringBuffer usage = new StringBuffer();
+
+ usage.append("Release-Checker is just a small tool checking releases \n");
+ usage.append("How to launch:\n");
+ usage.append("java -cp bin:commons-cli-1.1.jar:commons-collections-3.2.1.jar:commons-lang-2.4.jar:dom4j-1.6.1.jar:apache-rat-0.7-SNAPSHOT.jar:apache-rat-core-0.7-SNAPSHOT.jar org.apache.felix.release.checker.Release [ARGS]\n");
+ usage.append("Arguments:\n");
+ usage.append("\t -u or --url: URL to download the release [mandatory] \n");
+ usage.append("\t -n or --name: Name of the artifact [mandatory] \n");
+ usage.append("\t -v or --version: Version of the artifact [mandatory] \n");
+ usage.append("\t -c or --configuration: Set the configuration file to use \n");
+ usage.append("Example:\n");
+ usage.append("java -cp bin:commons-cli-1.1.jar:commons-collections-3.2.1.jar:commons-lang-2.4.jar:dom4j-1.6.1.jar:apache-rat-0.7-SNAPSHOT.jar:apache-rat-core-0.7-SNAPSHOT.jar org.apache.felix.release.checker.Release -u http://people.apache.org/~pauls/1.6.0/ -n org.apache.felix.bundlerepository -v 1.4.0 --offline");
+
+ System.out.println(usage);
+
+ }
+
+ public void clean() {
+ directory.delete();
+ }
+
+ public Map<String, File> getArtifacts() {
+ return artifacts;
+ }
+
+ public File getArtifactDirectory() {
+ return directory;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ private void printReport() {
+ StringBuffer report = new StringBuffer();
+ // Header
+ report.append("============================================================\n");
+ report.append("= Release Checking Report =\n");
+ report.append("============================================================\n");
+ report.append("\n");
+ report.append("I. Overview:\n");
+ report.append("\t Artifact name: " + name + "\n");
+ report.append("\t Artifact version: " + version + "\n");
+ if (downloadDate != null) {
+ report.append("\t Download date: " + DateFormat.getDateTimeInstance().format(downloadDate) + "\n");
+ }
+ report.append("\t Number of download files: " + artifacts.size() + "\n");
+ report.append("\t Directory: " + directory.getAbsolutePath() + "\n");
+ report.append("\n");
+ report.append("II. Result Overview:\n");
+ report.append("\t Number of checkers: " + checkers.size());
+ report.append("\t Success: " + success.size());
+ report.append("\t Warnings: " + warning.size());
+ report.append("\t Errors: " + error.size());
+ report.append("\t Skipped: " + skipped.size());
+ report.append("\n");
+ report.append("\n");
+ report.append("II. Result Details:\n");
+ for(Checker chk: checkers) {
+ String result = "\t[" + chk.getCheckerName() + "] ";
+ if (success.contains(chk)) {
+ if (warning.containsKey(chk)) {
+ result += " OK with warnings: \n";
+ List<String> warnings = warning.get(chk);
+ for(String warn:warnings) {
+ result += "\t\t[WARNING] " + warn +"\n";
+ }
+ } else {
+ result += " OK \n";
+ }
+ } else if (skipped.contains(chk)) {
+ result += " SKIPPED \n";
+ } else { // Failure
+ result += " FAILURE: \n";
+ List<String> err = error.get(chk);
+ for(String mess:err) {
+ result += "\t\t[ERROR] " + mess +"\n";
+ }
+ }
+ report.append(result);
+ }
+
+ report.append("============================================================\n");
+
+ System.out.println(report);
+ }
+
+
+}
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/ProjectLicenseChecker.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/ProjectLicenseChecker.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/ProjectLicenseChecker.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/ProjectLicenseChecker.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,31 @@
+package org.apache.felix.project.checker;
+
+import java.io.File;
+
+public class ProjectLicenseChecker implements Checker {
+
+ private Project release;
+
+ public void check() throws Exception {
+ File file = new File(release.getProjectRoot(), "LICENSE");
+ if (! file.exists()) {
+ file = new File(release.getProjectRoot(), "LICENCE");
+ if (! file.exists()) {
+ throw new Exception("Cannot find license file in " + file.getName());
+ }
+ }
+ }
+
+ public void clean() { }
+
+ public boolean prepare(Project release) throws Exception {
+ this.release = release;
+
+ return true;
+ }
+
+ public String getCheckerName() {
+ return "Project License Checker";
+ }
+
+}
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/ProjectNoticeChecker.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/ProjectNoticeChecker.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/ProjectNoticeChecker.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/ProjectNoticeChecker.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,27 @@
+package org.apache.felix.project.checker;
+
+import java.io.File;
+
+public class ProjectNoticeChecker implements Checker {
+ private Project release;
+
+ public void check() throws Exception {
+ File file = new File(release.getProjectRoot(), "NOTICE");
+ if (!file.exists()) {
+ throw new Exception("Cannot find license file in " + file.getName());
+ }
+
+ }
+
+ public void clean() { }
+
+ public boolean prepare(Project release) throws Exception {
+ this.release = release;
+ return true;
+ }
+
+ public String getCheckerName() {
+ return "Project notice Checker";
+ }
+
+}
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Sha1Checker.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Sha1Checker.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Sha1Checker.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Sha1Checker.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,66 @@
+package org.apache.felix.project.checker;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class Sha1Checker implements Checker {
+
+ public static final String SSL_PROPERTY = "SSL";
+
+ private List<File> files = new ArrayList<File>();
+ private Project release;
+
+ public void check() throws Exception {
+ for (File f : files) {
+ // Remove the .sha1 from the file name
+ int index = f.getName().lastIndexOf('.');
+ String n = f.getName().substring(0, index);
+
+ Command cmd = new Command();
+ cmd.executeCommand(release, release.getProperty(SSL_PROPERTY) + " sha1 " + n, false);
+ String out = cmd.getOutput();
+ String md5 = getSha1(f);
+ if (! out.contains(md5)) {
+ throw new Exception("Bad sha1 hash for " + n);
+ }
+ }
+ }
+
+ private String getSha1(File f) throws IOException {
+ FileReader fis = new FileReader (f);
+ BufferedReader br = new BufferedReader (fis);
+ String line = br.readLine();
+ int index = line.indexOf(' ');
+ return line.substring(index).trim();
+ }
+
+ public void clean() {
+ files.clear();
+ }
+
+ public boolean prepare(Project release) throws Exception {
+ this.release = release;
+ // Get all md5 and sha1 files
+ Map<String, File> maps = release.getArtifacts();
+ Iterator<String> it = maps.keySet().iterator();
+ while(it.hasNext()) {
+ String f = it.next();
+ if (f.endsWith(".sha1")) {
+ files.add(maps.get(f));
+ }
+ }
+
+ return true;
+ }
+
+ public String getCheckerName() {
+ return "SHA1 Signature Checker";
+ }
+
+}
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/SignatureBeautifiedChecker.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/SignatureBeautifiedChecker.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/SignatureBeautifiedChecker.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/SignatureBeautifiedChecker.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,63 @@
+package org.apache.felix.project.checker;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class SignatureBeautifiedChecker implements Checker {
+
+ List<File> files = new ArrayList<File>();
+
+ public void check() throws Exception {
+ for (File f : files) {
+ FileReader fis = new FileReader (f);
+ BufferedReader br = new BufferedReader (fis);
+ String line = br.readLine();
+
+ // Close the input stream
+ br.close();
+
+ // Check format : signature filename
+ String[] array = line.split(" ");
+ if (array.length < 2) {
+ throw new Exception("Bad signature, file name sounds missing in " + f.getName());
+ }
+
+ // Remove the .sha1 or .md5 from the file name
+ int index = f.getName().lastIndexOf('.');
+ String n = f.getName().substring(0, index);
+
+ if (! line.contains(n)) {
+ throw new Exception("The file name is missing in " + f.getName());
+ }
+
+ }
+ }
+
+ public void clean() {
+ files.clear();
+ }
+
+ public boolean prepare(Project release) throws Exception {
+ // Get all md5 and sha1 files
+ Map<String, File> maps = release.getArtifacts();
+ Iterator<String> it = maps.keySet().iterator();
+ while(it.hasNext()) {
+ String f = it.next();
+ if (f.endsWith(".md5") || f.endsWith(".sha1")) {
+ files.add(maps.get(f));
+ }
+ }
+
+ return true;
+ }
+
+ public String getCheckerName() {
+ return "Signature beautification Checker";
+ }
+
+}
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/SignatureChecker.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/SignatureChecker.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/SignatureChecker.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/SignatureChecker.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,51 @@
+package org.apache.felix.project.checker;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class SignatureChecker implements Checker {
+
+ private List<File> files = new ArrayList<File>();
+ private Project release;
+
+ public void check() throws Exception {
+ for (File f : files) {
+ // Remove the .asc from the file name
+ int index = f.getName().lastIndexOf('.');
+ String n = f.getName().substring(0, index);
+
+ Command cmd = new Command();
+ cmd.executeCommand(release, "/usr/local/bin/gpg --verify " + f.getName() + " " + n, false);
+ String err = cmd.getError();
+ if (!err.contains("(CODE SIGNING KEY)")) {
+ throw new Exception("Cannot verify the signature of " + n + " : " + err);
+ }
+ }
+ }
+
+ public void clean() {
+ files.clear();
+ }
+
+ public boolean prepare(Project release) throws Exception {
+ this.release = release;
+ // Get all md5 and sha1 files
+ Map<String, File> maps = release.getArtifacts();
+ Iterator<String> it = maps.keySet().iterator();
+ while(it.hasNext()) {
+ String f = it.next();
+ if (f.endsWith(".asc")) {
+ files.add(maps.get(f));
+ }
+ }
+ return true;
+ }
+
+ public String getCheckerName() {
+ return "ASC signature Checker";
+ }
+
+}
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/TagChecker.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/TagChecker.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/TagChecker.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/TagChecker.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,125 @@
+package org.apache.felix.project.checker;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.parser.ParserDelegator;
+
+public class TagChecker implements Checker {
+
+ public static final String SVN_URL="SVN_URL";
+ public static final String TITLE_REGEX = ".* - Revision (.*): (.*)";
+ public static final Pattern TITLE_PATTERN = Pattern.compile(TITLE_REGEX);
+
+
+ private URL url;
+ private String name;
+ private String version;
+
+ public void check() throws Exception {
+ // Load the page and check that the title is correct
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ System.out.println("Opening stream " + url);
+
+ InputStream is = connection.getInputStream();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ int cc = 0;
+ do {
+ int i = is.read();
+ if (i == -1)
+ break;
+ cc++;
+ bos.write(i);
+ } while (true);
+
+
+ byte[] bytes = bos.toByteArray();
+
+ try {
+ bos.close();
+ is.close();
+ connection.disconnect();
+ } catch (Exception e) {
+ throw new Exception("Cannot get urls : " + e.getMessage());
+ }
+
+ parsePage(bytes);
+ }
+
+ public void clean() { }
+
+ public String getCheckerName() {
+ return "Release Tag Checker";
+ }
+
+ public boolean prepare(Project release) throws Exception {
+ String root = release.getProperty(SVN_URL);
+ if (root == null) {
+ return false;
+ } else {
+ url = new URL(root + release.getName() + "-" + release.getVersion());
+ }
+
+ name = release.getName();
+ version = release.getVersion();
+
+ return true;
+ }
+
+ private void parsePage(byte[] bytes) throws Exception {
+ BufferedReader reader = new BufferedReader(new StringReader(new String(bytes)));
+ Parser parser = new Parser();
+ new ParserDelegator().parse(reader,parser, true);
+ parseTitle(parser.title);
+
+ }
+
+ private void parseTitle(String title) throws Exception {
+ Matcher matcher = TITLE_PATTERN.matcher(title);
+ if (matcher.matches()) {
+ String path = matcher.group(2);
+ if (! path.contains(name+"-"+version)) {
+ throw new Exception("Release revision page not valid, expected " + name+"-"+version + ", found " + path);
+ }
+ System.out.println("revision : " + matcher.group(1) + " - " + path);
+ } else {
+ throw new Exception("Release revision page not valid, expected " + TITLE_REGEX + ", found " + title);
+ }
+ }
+
+ private class Parser extends HTMLEditorKit.ParserCallback {
+ private String title;
+ private boolean enable = false;
+
+ public void handleText(char[] data, int pos) {
+ if (enable) {
+ title = new String(data);
+ }
+ }
+
+ public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
+ enable = t.equals(HTML.Tag.TITLE);
+ }
+
+ public void handleEndTag(HTML.Tag t, int pos) {
+ if (enable) {
+ enable = false;
+ }
+ }
+ }
+
+
+
+}
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/UsedLicenseChecker.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/UsedLicenseChecker.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/UsedLicenseChecker.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/UsedLicenseChecker.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,159 @@
+package org.apache.felix.project.checker;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+public class UsedLicenseChecker implements Checker {
+
+ public static final String BUNDLE_MANIFEST_VERSION = "Bundle-ManifestVersion";
+ public static final String BUNDLE_IMPORT_PACKAGES = "Import-Package";
+
+
+ private Project release;
+ private JarFile jar;
+ private List<String> packages;
+
+ public void check() throws Exception {
+
+
+ // filter(packages); // Remove apache (no filter)
+ check(packages); // Check the others references against the checkers.
+
+ if (! packages.isEmpty()) {
+ // Unrecognized packages.
+ for (String r : packages) {
+ release.warning(this, "Cannot match " + r + " with a known license");
+ }
+ }
+ }
+
+// private void filter(List<String> referred) {
+// List<String> toRemove = new ArrayList<String>();
+// for (String s : referred) {
+// if (s.startsWith("org.apache.")) {
+// toRemove.add(s);
+// }
+// }
+// referred.removeAll(toRemove);
+// }
+
+ private void check(List<String> referred) {
+ List<String> toRemove = new ArrayList<String>();
+ for (String s : referred) {
+ if (toRemove.contains(s)) {
+ continue; // Already checked.
+ }
+
+ License checker = getLicenseByPrefix(s);
+
+ if (checker != null) {
+ try {
+ License found = getLicenseByKeyword(checker.getKeyword());
+ checker.check(this, release, found);
+ // Remove package.
+ for (String x : referred) {
+ if (x.startsWith(s)) {
+ toRemove.add(x);
+ }
+ }
+ } catch (Exception e) {
+ release.error(this, "Included code does not have an appropriate licence " + s, e.getMessage());
+ }
+ }
+
+ }
+ referred.removeAll(toRemove);
+ }
+
+ public License getLicenseByPrefix(String packagename) {
+ for (License checker : release.getKnownLicense()) {
+ for (int i = 0; i < checker.getPackages().length; i++) {
+ if (packagename.startsWith(checker.getPackages()[i])) {
+ return checker;
+ }
+ }
+
+ }
+ return null;
+ }
+
+ public License getLicenseByKeyword(String key) {
+ Notice notice = release.getNotice();
+ License found = null;
+ List<License> lics = notice.getUsed();
+ for (License lic : lics) {
+ if (lic.getText().contains(key)) {
+ if (found == null) {
+ found = lic;
+ } else {
+ release.warning(this, "Ambiguity found when analyzing the notice file, several licenses match with " + key
+ + "(" + found.getProvider() + ", " + lic.getProvider() + ")");
+ }
+ }
+ }
+ return found;
+ }
+
+ public void clean() { }
+
+ public String getCheckerName() {
+ return "Used License Checker";
+ }
+
+ public boolean prepare(Project release) throws Exception {
+ this.release = release;
+ jar = release.getJar();
+ Object o = jar.getManifest().getMainAttributes().getValue(BUNDLE_MANIFEST_VERSION);
+ if (o == null) {
+ System.out.println("Not a bundle");
+ return false;
+ }
+
+ String imports = (String) jar.getManifest().getMainAttributes().getValue(BUNDLE_IMPORT_PACKAGES);
+ processImports(imports);
+
+
+ return true;
+ }
+
+ private void processImports(String imports) {
+ // Remove '\n'
+ imports = imports.replaceAll("\n", "");
+ // Remove spaces
+ imports = imports.replaceAll(" ", "");
+
+ String[] clauses = null;
+
+ if (imports.contains(",")) {
+ clauses = imports.split(",");
+ } else {
+ clauses = new String[] {imports};
+ }
+
+ packages = new ArrayList<String>();
+ for(String s : clauses) {
+ int index = s.indexOf(';');
+ if (index != -1) {
+ String pack = s.substring(0, index);
+ packages.add(pack);
+ } else {
+ packages.add(s);
+ }
+ }
+
+ // Remove packages contained in the jar file
+ List<String> toRemove = new ArrayList<String>();
+ for (String s : packages) {
+ String directory = s.replace(".", "/");
+ ZipEntry je = jar.getEntry(directory);
+ if (je != null) {
+ toRemove.add(s);
+ }
+ }
+ packages.removeAll(toRemove);
+
+ }
+
+}
Added: felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Utils.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Utils.java?rev=763213&view=auto
==============================================================================
--- felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Utils.java (added)
+++ felix/sandbox/clement/Project-Checker/src/org/apache/felix/project/checker/Utils.java Wed Apr 8 12:30:27 2009
@@ -0,0 +1,79 @@
+package org.apache.felix.project.checker;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class Utils {
+
+ public static File expand(File directory, String name, ZipEntry ze, ZipFile zf) throws IOException {
+ InputStream is = zf.getInputStream(ze);
+ File file = new File(directory,name);
+ FileOutputStream os = new FileOutputStream(file);
+ int c;
+ int i = 0;
+ while ((c = is.read()) >= 0) {
+ os.write(c);
+ i++;
+ }
+ is.close();
+ return file;
+ }
+
+ public static boolean delete(File file) {
+ return file.delete();
+ }
+
+ public static boolean compare(File a, File b) {
+ try {
+
+ if (a == null && b != null) {
+ return false;
+ }
+
+ if (b == null && a != null) {
+ return false;
+ }
+
+ BufferedReader br1 = new BufferedReader(new FileReader(a));
+ BufferedReader br2 = new BufferedReader(new FileReader(b));
+
+ StringBuffer report = new StringBuffer();
+
+ String l1 = null;
+ String l2 = null;
+ while ((l1 = br1.readLine()) != null) {
+ l2 = br2.readLine();
+ if (! l1.equals(l2)) {
+ report.append("Expected : " + l1 + "\n");
+ report.append("Found : "+ l2 + "\n");
+ report.append("\n");
+ }
+ }
+
+ br1.close();
+ br2.close();
+
+ if (report.length() > 0) {
+ System.out.println("Differences found between " + a.getAbsolutePath() + " and " + a.getAbsolutePath());
+ System.out.println(report);
+ return false;
+ } else {
+ return true;
+ }
+
+ } catch (IOException e) {
+ System.err.println("Issue occurs when comparing files " + e.getMessage());
+ return false;
+ }
+ }
+
+}