Skip to content

Commit

Permalink
FsfLicenseDataParser: Fill in implementation
Browse files Browse the repository at this point in the history
Pull the index (mapping from SPDX IDs to FSF IDs) during
initialization, and then lookup each license as needed with a separate
request.

An implementation that hits isSpdxLicenseFsfLibre multiple times (or
which wanted to extract multiple values for a single license) would be
more efficient if we cached the per-license FSF response.  I've left
that off for now because our only consumer is just asking for
libre-ness, and only doing that once per license.

I've used a Boolean for the isSpdxLicenseFsfLibre to get a nullable
value, so we can represent:

* "yes, the FSF marks that license 'libre'" (true),
* "no, the FSF considers that license non-free" (false), and
* "we don't know the FSF opinion for that license" (null).
  • Loading branch information
wking committed Oct 25, 2017
1 parent 26f9954 commit 47f1a90
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 10 deletions.
11 changes: 10 additions & 1 deletion src/org/spdx/tools/LicenseRDFAGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,16 @@ private static void writeLicenseList(String version, String releaseDate,
* @param license
*/
private static void addExternalMetaData(SpdxListedLicense license) {
license.setFsfLibre(FsfLicenseDataParser.getFsfLicenseDataParser().isSpdxLicenseFsfLibre(license.getLicenseId()));
Boolean libre = null;
try {
libre = FsfLicenseDataParser.getFsfLicenseDataParser().isSpdxLicenseFsfLibre(license.getLicenseId());
} catch (LicenseGeneratorException e) {
System.out.println(e.getMessage());
libre = null;
}
if (libre != null) {
license.setFsfLibre(libre);
}
}

/**
Expand Down
81 changes: 72 additions & 9 deletions src/org/spdx/tools/licensegenerator/FsfLicenseDataParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@
*/
package org.spdx.tools.licensegenerator;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.spdx.tools.LicenseGeneratorException;

/**
* Singleton class which returns information maintained by the Free Software Foundation
*
Expand All @@ -25,14 +42,40 @@
*
*/
public class FsfLicenseDataParser {

private static FsfLicenseDataParser fsfLicenseDataParser = null;

private FsfLicenseDataParser() {
//TODO: Initialize any cached data
private static Map<String, String> fsfID;

private FsfLicenseDataParser() throws LicenseGeneratorException {
fsfID = new HashMap<String, String>();
URL url;
try {
url = new URL("https://wking.github.io/fsf-api/licenses.json");
} catch (MalformedURLException e) {
throw new LicenseGeneratorException("invalid FSF license-list URL", e);
}
try {
Reader reader = new BufferedReader(new InputStreamReader(url.openStream()));
JSONObject index = (JSONObject)JSONValue.parseWithException(reader);
Iterator iterator = index.entrySet().iterator();
while (iterator.hasNext()) {
Entry entry = (Entry)iterator.next();
JSONObject value = (JSONObject)entry.getValue();
JSONObject identifiers = (JSONObject)value.get("identifiers");
if (identifiers == null) {
continue;
}
String spdx = (String)identifiers.get("spdx");
if (spdx != null) {
fsfID.put(spdx, (String)entry.getKey());
}
}
} catch (IOException|ParseException e) {
throw new LicenseGeneratorException("failure processing FSF license-list", e);
}
}
public static synchronized FsfLicenseDataParser getFsfLicenseDataParser() {

public static synchronized FsfLicenseDataParser getFsfLicenseDataParser() throws LicenseGeneratorException {
if (fsfLicenseDataParser == null) {
fsfLicenseDataParser = new FsfLicenseDataParser();
}
Expand All @@ -44,9 +87,29 @@ public static synchronized FsfLicenseDataParser getFsfLicenseDataParser() {
* @param spdxLicenseId
* @return
*/
public boolean isSpdxLicenseFsfLibre(String spdxLicenseId) {
// TODO Implement
return false;
public Boolean isSpdxLicenseFsfLibre(String spdxLicenseId) throws LicenseGeneratorException {
String id = fsfID.get(spdxLicenseId);
if (id == null) {
return null;
}
URL url;
try {
url = new URL(String.format("https://wking.github.io/fsf-api/%s.json", id));
} catch (MalformedURLException e) {
throw new LicenseGeneratorException("invalid FSF license-list URL", e);
}
JSONArray tags;
try {
Reader reader = new BufferedReader(new InputStreamReader(url.openStream()));
JSONObject license = (JSONObject)JSONValue.parseWithException(reader);
tags = (JSONArray)license.get("tags");
} catch (IOException|ParseException e) {
throw new LicenseGeneratorException(String.format("failure processing FSF metadata for %s", id), e);
}
if (tags == null) {
return null;
}
return tags.contains("libre");
}

}

0 comments on commit 47f1a90

Please sign in to comment.