diff --git a/pom.xml b/pom.xml
index daaf581..202f3c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
org.spdx
licenseListPublisher
- 2.1.16
+ 2.1.17
License List Publisher
Tool that generates license data found in the license-list-data repository from the license-list-XML source
diff --git a/src/org/spdx/htmltemplates/ExceptionHtml.java b/src/org/spdx/htmltemplates/ExceptionHtml.java
new file mode 100644
index 0000000..01a5bd5
--- /dev/null
+++ b/src/org/spdx/htmltemplates/ExceptionHtml.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2014 Source Auditor 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.htmltemplates;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.List;
+import java.util.Map;
+
+import org.spdx.html.InvalidLicenseTemplateException;
+import org.spdx.rdfparser.license.ListedLicenseException;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheException;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+
+/**
+ * Manages the production of an HTML file based on an SpdxLicenseRestriction (a.k.a License Exception)
+ * @author Gary O'Neall
+ *
+ */
+public class ExceptionHtml {
+
+ static final String TEMPLATE_CLASS_PATH = "resources" + "/" + "htmlTemplate";
+ static final String TEMPLATE_ROOT_PATH = "resources" + File.separator + "htmlTemplate";
+ static final String HTML_TEMPLATE = "ExceptionHTMLTemplate.html";
+
+ Map mustacheMap = Maps.newHashMap();
+
+ /**
+ * @param exception
+ * @throws InvalidLicenseTemplateException
+ */
+ public ExceptionHtml(ListedLicenseException exception) throws InvalidLicenseTemplateException {
+ List alSourceUrls = Lists.newArrayList();
+ String[] sourceUrls = exception.getSeeAlso();
+ if (sourceUrls != null) {
+ for (String sourceUrl: sourceUrls) {
+ alSourceUrls.add(sourceUrl);
+ }
+ }
+ mustacheMap.put("name", exception.getName());
+ mustacheMap.put("id", exception.getLicenseExceptionId());
+ mustacheMap.put("text", exception.getExceptionTextHtml());
+ mustacheMap.put("getSourceUrl", alSourceUrls);
+ mustacheMap.put("notes", exception.getComment());
+ mustacheMap.put("deprecated", exception.isDeprecated());
+ mustacheMap.put("deprecatedVersion", exception.getDeprecatedVersion());
+ }
+
+ /**
+ * @param exceptionHtmlFile
+ * @param exceptionHtmlTocReference
+ * @throws IOException
+ * @throws MustacheException
+ */
+ public void writeToFile(File exceptionHtmlFile,
+ String exceptionHtmlTocReference) throws IOException, MustacheException {
+ mustacheMap.put("exceptionTocReference", exceptionHtmlTocReference);
+ FileOutputStream stream = null;
+ OutputStreamWriter writer = null;
+ if (!exceptionHtmlFile.exists()) {
+ if (!exceptionHtmlFile.createNewFile()) {
+ throw(new IOException("Can not create new file "+exceptionHtmlFile.getName()));
+ }
+ }
+ String templateDirName = TEMPLATE_ROOT_PATH;
+ File templateDirectoryRoot = new File(templateDirName);
+ if (!(templateDirectoryRoot.exists() && templateDirectoryRoot.isDirectory())) {
+ templateDirName = TEMPLATE_CLASS_PATH;
+ }
+ try {
+ stream = new FileOutputStream(exceptionHtmlFile);
+ writer = new OutputStreamWriter(stream, "UTF-8");
+ DefaultMustacheFactory builder = new DefaultMustacheFactory(templateDirName);
+ Mustache mustache = builder.compile(HTML_TEMPLATE);
+ mustache.execute(writer, mustacheMap);
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+}
diff --git a/src/org/spdx/htmltemplates/ExceptionHtmlToc.java b/src/org/spdx/htmltemplates/ExceptionHtmlToc.java
new file mode 100644
index 0000000..50937a7
--- /dev/null
+++ b/src/org/spdx/htmltemplates/ExceptionHtmlToc.java
@@ -0,0 +1,277 @@
+/**
+ * Copyright (c) 2014 Source Auditor 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.htmltemplates;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.spdx.rdfparser.license.LicenseException;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheException;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Generates the HTML Table of Contents for License Exceptions
+ * @author Gary O'Neall
+ *
+ */
+public class ExceptionHtmlToc {
+ static final String TEMPLATE_CLASS_PATH = "resources" + "/" + "htmlTemplate";
+ static final String TEMPLATE_ROOT_PATH = "resources" + File.separator + "htmlTemplate";
+ static final String HTML_TEMPLATE = "ExceptionsTocHTMLTemplate.html";
+
+ public static class DeprecatedExceptionRow {
+ private int refNumber;
+ String licenseExceptionId;
+ private String reference;
+ private String exceptionName;
+ private String deprecatedVersion;
+
+ public DeprecatedExceptionRow(String licenseExceptionId, String exceptionName,
+ int refNumber, String reference, String deprecatedVersion) {
+ this.licenseExceptionId = licenseExceptionId;
+ this.exceptionName = exceptionName;
+ this.refNumber = refNumber;
+ this.reference = reference;
+ this.deprecatedVersion = deprecatedVersion;
+ }
+
+ /**
+ * @return the licenseExceptionId
+ */
+ public String getLicenseExceptionId() {
+ return licenseExceptionId;
+ }
+
+
+ /**
+ * @param licenseExceptionId the licenseExceptionId to set
+ */
+ public void setLicenseExceptionId(String licenseExceptionId) {
+ this.licenseExceptionId = licenseExceptionId;
+ }
+
+
+ /**
+ * @return the refNumber
+ */
+ public int getRefNumber() {
+ return refNumber;
+ }
+
+ /**
+ * @param refNumber the refNumber to set
+ */
+ public void setRefNumber(int refNumber) {
+ this.refNumber = refNumber;
+ }
+
+ /**
+ * @return the reference
+ */
+ public String getReference() {
+ return reference;
+ }
+
+ /**
+ * @param reference the reference to set
+ */
+ public void setReference(String reference) {
+ this.reference = reference;
+ }
+
+ /**
+ * @return the exceptionName
+ */
+ public String getExceptionName() {
+ return exceptionName;
+ }
+
+ /**
+ * @param exceptionName the exceptionName to set
+ */
+ public void setExceptionName(String exceptionName) {
+ this.exceptionName = exceptionName;
+ }
+
+ /**
+ * @return the deprecatedVersion
+ */
+ public String getDeprecatedVersion() {
+ return deprecatedVersion;
+ }
+
+ /**
+ * @param deprecatedVersion the deprecatedVersion to set
+ */
+ public void setDeprecatedVersion(String deprecatedVersion) {
+ this.deprecatedVersion = deprecatedVersion;
+ }
+ }
+
+ /**
+ * Holds the data one of the list rows of exceptions
+ * @author Gary O'Neall
+ *
+ */
+ public static class ExceptionRow {
+ private int refNumber;
+ private String reference;
+ private String exceptionName;
+ /**
+ * @return the refNumber
+ */
+ public int getRefNumber() {
+ return refNumber;
+ }
+
+ /**
+ * @param refNumber the refNumber to set
+ */
+ public void setRefNumber(int refNumber) {
+ this.refNumber = refNumber;
+ }
+
+ /**
+ * @return the reference
+ */
+ public String getReference() {
+ return reference;
+ }
+
+ /**
+ * @param reference the reference to set
+ */
+ public void setReference(String reference) {
+ this.reference = reference;
+ }
+
+ /**
+ * @return the exceptionName
+ */
+ public String getExceptionName() {
+ return exceptionName;
+ }
+
+ /**
+ * @param exceptionName the exceptionName to set
+ */
+ public void setExceptionName(String exceptionName) {
+ this.exceptionName = exceptionName;
+ }
+
+ /**
+ * @return the licenseExceptionId
+ */
+ public String getLicenseExceptionId() {
+ return licenseExceptionId;
+ }
+
+ /**
+ * @param licenseExceptionId the licenseExceptionId to set
+ */
+ public void setLicenseExceptionId(String licenseExceptionId) {
+ this.licenseExceptionId = licenseExceptionId;
+ }
+
+ private String licenseExceptionId;
+
+ public ExceptionRow(String licenseExceptionId, String exceptionName,
+ int refNumber, String reference) {
+ this.licenseExceptionId = licenseExceptionId;
+ this.exceptionName = exceptionName;
+ this.refNumber = refNumber;
+ this.reference = reference;
+ }
+ }
+
+ List exceptions = Lists.newArrayList();
+ List deprecatedExceptions = Lists.newArrayList();
+
+ int currentRefNum = 1;
+
+ /**
+ * Add an exception to the table of contents
+ * @param exception
+ * @param exceptionHTMLReference
+ */
+ public void addException(LicenseException exception,
+ String exceptionHTMLReference) {
+ exceptions.add(new ExceptionRow(
+ StringEscapeUtils.escapeHtml4(exception.getLicenseExceptionId()),
+ StringEscapeUtils.escapeHtml4(exception.getName()),
+ currentRefNum++, exceptionHTMLReference));
+ }
+
+ public void addDeprecatedException(LicenseException exception,
+ String exceptionHTMLReference, String deprecatedVersion) {
+ deprecatedExceptions.add(new DeprecatedExceptionRow(
+ StringEscapeUtils.escapeHtml4(exception.getLicenseExceptionId()),
+ StringEscapeUtils.escapeHtml4(exception.getName()),
+ currentRefNum++, exceptionHTMLReference, deprecatedVersion));
+ }
+
+ /**
+ * Creates and writes an Exception Table of Contents file
+ * @param exceptionTocFile file to write to
+ * @param version Version of the License List
+ * @throws IOException
+ * @throws MustacheException
+ */
+ public void writeToFile(File exceptionTocFile, String version) throws MustacheException, IOException {
+
+ Map mustacheMap = Maps.newHashMap();
+ mustacheMap.put("version", StringEscapeUtils.escapeHtml4(version));
+ mustacheMap.put("listedExceptions", exceptions);
+ mustacheMap.put("deprecatedExceptions", deprecatedExceptions);
+ FileOutputStream stream = null;
+ OutputStreamWriter writer = null;
+ if (!exceptionTocFile.exists()) {
+ if (!exceptionTocFile.createNewFile()) {
+ throw(new IOException("Can not create new file "+exceptionTocFile.getName()));
+ }
+ }
+ String templateDirName = TEMPLATE_ROOT_PATH;
+ File templateDirectoryRoot = new File(templateDirName);
+ if (!(templateDirectoryRoot.exists() && templateDirectoryRoot.isDirectory())) {
+ templateDirName = TEMPLATE_CLASS_PATH;
+ }
+ try {
+ stream = new FileOutputStream(exceptionTocFile);
+ writer = new OutputStreamWriter(stream, "UTF-8");
+ DefaultMustacheFactory builder = new DefaultMustacheFactory(templateDirName);
+ Mustache mustache = builder.compile(HTML_TEMPLATE);
+ mustache.execute(writer, mustacheMap);
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+
+}
diff --git a/src/org/spdx/htmltemplates/InvalidLicenseHtmlTemplateException.java b/src/org/spdx/htmltemplates/InvalidLicenseHtmlTemplateException.java
new file mode 100644
index 0000000..181ce10
--- /dev/null
+++ b/src/org/spdx/htmltemplates/InvalidLicenseHtmlTemplateException.java
@@ -0,0 +1,58 @@
+/**
+ *
+ */
+package org.spdx.htmltemplates;
+
+/**
+ * @author Gary O'Neall
+ *
+ * Exceptions related to HTML license templates
+ *
+ */
+public class InvalidLicenseHtmlTemplateException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ *
+ */
+ public InvalidLicenseHtmlTemplateException() {
+ super();
+ }
+
+ /**
+ * @param arg0
+ */
+ public InvalidLicenseHtmlTemplateException(String arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ */
+ public InvalidLicenseHtmlTemplateException(Throwable arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ */
+ public InvalidLicenseHtmlTemplateException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ * @param arg2
+ * @param arg3
+ */
+ public InvalidLicenseHtmlTemplateException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
+ super(arg0, arg1, arg2, arg3);
+ }
+
+}
diff --git a/src/org/spdx/htmltemplates/LicenseHTMLFile.java b/src/org/spdx/htmltemplates/LicenseHTMLFile.java
new file mode 100644
index 0000000..4168205
--- /dev/null
+++ b/src/org/spdx/htmltemplates/LicenseHTMLFile.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2011 Source Auditor 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.htmltemplates;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.spdx.html.InvalidLicenseTemplateException;
+import org.spdx.rdfparser.license.SpdxListedLicense;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheException;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * This class contains a formatted HTML file for a given license. Specific
+ * formatting information is contained in this file.
+ * @author Gary O'Neall
+ *
+ */
+public class LicenseHTMLFile {
+
+ static final String TEMPLATE_CLASS_PATH = "resources" + "/" + "htmlTemplate";
+ static final String TEMPLATE_ROOT_PATH = "resources" + File.separator + "htmlTemplate";
+ static final String TEMPLATE_FILE_NAME = "LicenseHTMLTemplate.html";
+ static final boolean USE_SITE = false; // set to true to use the site name for the link of external web pages
+
+ static final Pattern SITE_PATTERN = Pattern.compile("http://(.*)\\.(.*)(\\.org|\\.com|\\.net|\\.info)");
+
+ /**
+ * Parses a URL and stores the site name and the original URL
+ * @author Gary O'Neall
+ *
+ */
+ public static class FormattedUrl {
+ String url;
+ public FormattedUrl(String url) {
+ this.url = url;
+ }
+ public String getUrl() {
+ return this.url;
+ }
+ public void setUrl(String url) {
+ this.url = url;
+ }
+ public String getSite() {
+ return getSiteFromUrl(url);
+ }
+
+ @SuppressWarnings("unused")
+ private String getSiteFromUrl(String url) {
+ Matcher matcher = SITE_PATTERN.matcher(url);
+ if (matcher.find() && USE_SITE) {
+ int numGroups = matcher.groupCount();
+ return matcher.group(numGroups-1);
+ } else {
+ return url;
+ }
+ }
+ }
+ private SpdxListedLicense license;
+ /**
+ * @param templateFileName File name for the Mustache template file
+ * @param license Listed license to be used
+ * @param isDeprecated True if the license has been deprecated
+ * @param deprecatedVersion Version since the license has been deprecated (null if not deprecated)
+ */
+ public LicenseHTMLFile(SpdxListedLicense license) {
+ this.license = license;
+ }
+
+ public LicenseHTMLFile() {
+ this(null);
+ }
+
+ /**
+ * @return the license
+ */
+ public SpdxListedLicense getLicense() {
+ return license;
+ }
+
+ /**
+ * @param license the license to set
+ */
+ public void setLicense(SpdxListedLicense license) {
+ this.license = license;
+ }
+
+ public void writeToFile(File htmlFile, String tableOfContentsReference) throws IOException, MustacheException, InvalidLicenseTemplateException {
+ FileOutputStream stream = null;
+ OutputStreamWriter writer = null;
+ if (!htmlFile.exists()) {
+ if (!htmlFile.createNewFile()) {
+ throw(new IOException("Can not create new file "+htmlFile.getName()));
+ }
+ }
+ String templateDirName = TEMPLATE_ROOT_PATH;
+ File templateDirectoryRoot = new File(templateDirName);
+ if (!(templateDirectoryRoot.exists() && templateDirectoryRoot.isDirectory())) {
+ templateDirName = TEMPLATE_CLASS_PATH;
+ }
+ try {
+ stream = new FileOutputStream(htmlFile);
+ writer = new OutputStreamWriter(stream, "UTF-8");
+ DefaultMustacheFactory builder = new DefaultMustacheFactory(templateDirName);
+ Map mustacheMap = buildMustachMap();
+ Mustache mustache = builder.compile(TEMPLATE_FILE_NAME);
+ mustache.execute(writer, mustacheMap);
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+ /**
+ * @return
+ * @throws
+ * @throws LicenseTemplateRuleException
+ */
+ private Map buildMustachMap() throws InvalidLicenseTemplateException {
+ Map retval = Maps.newHashMap();
+ if (license != null) {
+ retval.put("licenseId", license.getLicenseId());
+ String licenseTextHtml = license.getLicenseTextHtml();
+ retval.put("licenseText", licenseTextHtml);
+ retval.put("licenseName", license.getName());
+ String notes;
+ if (license.getComment() != null && !license.getComment().isEmpty()) {
+ notes = license.getComment();
+ } else {
+ notes = null;
+ }
+ String templateText = license.getStandardLicenseTemplate();
+ if (templateText == null) {
+ templateText = StringEscapeUtils.escapeHtml4(license.getLicenseText());
+ }
+ retval.put("standardLicenseTemplate", templateText);
+ retval.put("notes", notes);
+ retval.put("osiApproved", license.isOsiApproved());
+ retval.put("fsfLibre", license.isFsfLibre());
+ retval.put("notFsfLibre", license.isNotFsfLibre());
+ List otherWebPages = Lists.newArrayList();
+ if (license.getSeeAlso() != null && license.getSeeAlso().length > 0) {
+ for (String sourceUrl : license.getSeeAlso()) {
+ if (sourceUrl != null && !sourceUrl.isEmpty()) {
+ FormattedUrl formattedUrl = new FormattedUrl(sourceUrl);
+ otherWebPages.add(formattedUrl);
+ }
+ }
+ if (otherWebPages.size() == 0) {
+ otherWebPages = null; // Force the template to print None
+ }
+ retval.put("otherWebPages", otherWebPages);
+ retval.put("title", license.getName());
+ String header = license.getLicenseHeaderHtml();
+ if (header != null && header.trim().isEmpty()) {
+ header = null; // so the template will appropriately skip the header text
+ }
+ retval.put("licenseHeader", header);
+ }
+ }
+ retval.put("deprecated", this.license.isDeprecated());
+ retval.put("deprecatedVersion", this.license.getDeprecatedVersion());
+ return retval;
+ }
+
+}
diff --git a/src/org/spdx/htmltemplates/LicenseTOCHTMLFile.java b/src/org/spdx/htmltemplates/LicenseTOCHTMLFile.java
new file mode 100644
index 0000000..ebb8a33
--- /dev/null
+++ b/src/org/spdx/htmltemplates/LicenseTOCHTMLFile.java
@@ -0,0 +1,325 @@
+/**
+ * Copyright (c) 2011 Source Auditor 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.htmltemplates;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.List;
+import java.util.Map;
+
+import org.spdx.rdfparser.license.SpdxListedLicense;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheException;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * This class holds a formatted HTML file for a license table of contents
+ * @author Gary O'Neall
+ *
+ */
+public class LicenseTOCHTMLFile {
+
+ static final String TEMPLATE_CLASS_PATH = "resources" + "/" + "htmlTemplate";
+ static final String TEMPLATE_ROOT_PATH = "resources" + File.separator + "htmlTemplate";
+ static final String HTML_TEMPLATE = "TocHTMLTemplate.html";
+
+ public static class DeprecatedLicense {
+ private String reference;
+ private String refNumber;
+ private String licenseId;
+ private String licenseName;
+ private String deprecatedVersion;
+
+ public DeprecatedLicense(String reference, String refNumber,
+ String licenseId, String licenseName, String deprecatedVersion) {
+ this.reference = reference;
+ this.refNumber = refNumber;
+ this.licenseId = licenseId;
+ this.licenseName = licenseName;
+ this.deprecatedVersion = deprecatedVersion;
+ }
+
+ /**
+ * @return the reference
+ */
+ public String getReference() {
+ return reference;
+ }
+
+ /**
+ * @param reference the reference to set
+ */
+ public void setReference(String reference) {
+ this.reference = reference;
+ }
+
+ /**
+ * @return the refNumber
+ */
+ public String getRefNumber() {
+ return refNumber;
+ }
+
+ /**
+ * @param refNumber the refNumber to set
+ */
+ public void setRefNumber(String refNumber) {
+ this.refNumber = refNumber;
+ }
+
+ /**
+ * @return the licenseId
+ */
+ public String getLicenseId() {
+ return licenseId;
+ }
+
+ /**
+ * @param licenseId the licenseId to set
+ */
+ public void setLicenseId(String licenseId) {
+ this.licenseId = licenseId;
+ }
+
+ /**
+ * @return the licenseName
+ */
+ public String getLicenseName() {
+ return licenseName;
+ }
+
+ /**
+ * @param licenseName the licenseName to set
+ */
+ public void setLicenseName(String licenseName) {
+ this.licenseName = licenseName;
+ }
+
+ /**
+ * @return the deprecatedVersion
+ */
+ public String getDeprecatedVersion() {
+ return deprecatedVersion;
+ }
+
+ /**
+ * @param deprecatedVersion the deprecatedVersion to set
+ */
+ public void setDeprecatedVersion(String deprecatedVersion) {
+ this.deprecatedVersion = deprecatedVersion;
+ }
+ }
+
+ public static class ListedSpdxLicense {
+ private String reference;
+ private String refNumber;
+ private String licenseId;
+ private String osiApproved;
+ private String fsfLibre;
+ private String licenseName;
+
+ public ListedSpdxLicense() {
+ reference = null;
+ refNumber = null;
+ licenseId = null;
+ osiApproved = null;
+ licenseName = null;
+ fsfLibre = null;
+ }
+
+ public ListedSpdxLicense(String reference, String refNumber,
+ String licenseId, boolean isOsiApproved, Boolean fsfLibre, String licenseName) {
+ this.reference = reference;
+ this.refNumber = refNumber;
+ this.licenseId = licenseId;
+ if (isOsiApproved) {
+ this.osiApproved = "Y";
+ } else {
+ this.osiApproved = "";
+ }
+ if (fsfLibre != null && fsfLibre) {
+ this.fsfLibre = "Y";
+ } else {
+ this.fsfLibre = "";
+ }
+ this.licenseName = licenseName;
+ }
+
+ /**
+ * @return the reference
+ */
+ public String getReference() {
+ return reference;
+ }
+
+ /**
+ * @param reference the reference to set
+ */
+ public void setReference(String reference) {
+ this.reference = reference;
+ }
+
+ /**
+ * @return the refNumber
+ */
+ public String getRefNumber() {
+ return refNumber;
+ }
+
+ /**
+ * @param refNumber the refNumber to set
+ */
+ public void setRefNumber(String refNumber) {
+ this.refNumber = refNumber;
+ }
+
+ /**
+ * @return the licenseId
+ */
+ public String getLicenseId() {
+ return licenseId;
+ }
+
+ /**
+ * @param licenseId the licenseId to set
+ */
+ public void setLicenseId(String licenseId) {
+ this.licenseId = licenseId;
+ }
+
+ /**
+ * @return the osiApproved
+ */
+ public String getOsiApproved() {
+ return osiApproved;
+ }
+
+ public String getFsfLibre() {
+ return fsfLibre;
+ }
+
+ /**
+ * @param osiApproved the osiApproved to set
+ */
+ public void setOsiApproved(String osiApproved) {
+ this.osiApproved = osiApproved;
+ }
+
+ /**
+ * @return the licenseName
+ */
+ public String getLicenseName() {
+ return licenseName;
+ }
+
+ /**
+ * @param licenseName the licenseName to set
+ */
+ public void setLicenseName(String licenseName) {
+ this.licenseName = licenseName;
+ }
+ }
+
+ List listedLicenses = Lists.newArrayList();
+ List deprecatedLicenses = Lists.newArrayList();
+
+ private int currentRefNumber = 1;
+
+ String version;
+ String releaseDate;
+
+ private String generateVersionString(String version, String releaseDate) {
+ if (version == null || version.trim().isEmpty()) {
+ return "";
+ }
+ String retval = version.trim();
+ if (releaseDate != null && !releaseDate.trim().isEmpty()) {
+ retval = retval + " "+ releaseDate.trim();
+ }
+ return retval;
+ }
+ public LicenseTOCHTMLFile(String version, String releaseDate) {
+ this.version = version;
+ this.releaseDate = releaseDate;
+ }
+
+ public void addLicense(SpdxListedLicense license, String licHTMLReference) {
+ listedLicenses.add(new ListedSpdxLicense(licHTMLReference, String.valueOf(this.currentRefNumber),
+ license.getLicenseId(), license.isOsiApproved(), license.getFsfLibre(), license.getName()));
+ currentRefNumber++;
+ }
+
+ public void writeToFile(File htmlFile) throws IOException, MustacheException {
+ FileOutputStream stream = null;
+ OutputStreamWriter writer = null;
+ if (!htmlFile.exists()) {
+ if (!htmlFile.createNewFile()) {
+ throw(new IOException("Can not create new file "+htmlFile.getName()));
+ }
+ }
+ String templateDirName = TEMPLATE_ROOT_PATH;
+ File templateDirectoryRoot = new File(templateDirName);
+ if (!(templateDirectoryRoot.exists() && templateDirectoryRoot.isDirectory())) {
+ templateDirName = TEMPLATE_CLASS_PATH;
+ }
+ try {
+ stream = new FileOutputStream(htmlFile);
+ writer = new OutputStreamWriter(stream, "UTF-8");
+ DefaultMustacheFactory builder = new DefaultMustacheFactory(templateDirName);
+ Map mustacheMap = buildMustachMap();
+ Mustache mustache = builder.compile(HTML_TEMPLATE);
+ mustache.execute(writer, mustacheMap);
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+ /**
+ * Build the a hash map to map the variables in the template to the values
+ * @return
+ */
+ private Map buildMustachMap() {
+ Map retval = Maps.newHashMap();
+ retval.put("version", generateVersionString(version, releaseDate));
+ retval.put("listedLicenses", this.listedLicenses);
+ retval.put("deprecatedLicenses", this.deprecatedLicenses);
+ return retval;
+ }
+ /**
+ * @param deprecatedLicense
+ * @param licHTMLReference
+ */
+ public void addDeprecatedLicense(SpdxListedLicense deprecatedLicense,
+ String licHTMLReference) {
+ deprecatedLicenses.add(new DeprecatedLicense(licHTMLReference, String.valueOf(this.currentRefNumber),
+ deprecatedLicense.getLicenseId(),
+ deprecatedLicense.getName(),
+ deprecatedLicense.getDeprecatedVersion()));
+ currentRefNumber++;
+ }
+
+
+}
diff --git a/src/org/spdx/htmltemplates/package-info.java b/src/org/spdx/htmltemplates/package-info.java
new file mode 100644
index 0000000..ec1ec77
--- /dev/null
+++ b/src/org/spdx/htmltemplates/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Classes that manage the HTML templates used to output HTML formated license information
+ *
+ * @author Gary O'Neall
+ *
+ */
+package org.spdx.htmltemplates;
\ No newline at end of file
diff --git a/src/org/spdx/licenselistpublisher/licensegenerator/LicenseRdfaFormatWriter.java b/src/org/spdx/licenselistpublisher/licensegenerator/LicenseRdfaFormatWriter.java
index 369b038..6ddfa19 100644
--- a/src/org/spdx/licenselistpublisher/licensegenerator/LicenseRdfaFormatWriter.java
+++ b/src/org/spdx/licenselistpublisher/licensegenerator/LicenseRdfaFormatWriter.java
@@ -18,11 +18,11 @@
import java.io.File;
import java.io.IOException;
-import org.spdx.html.ExceptionHtml;
-import org.spdx.html.ExceptionHtmlToc;
+import org.spdx.htmltemplates.ExceptionHtml;
+import org.spdx.htmltemplates.ExceptionHtmlToc;
import org.spdx.html.InvalidLicenseTemplateException;
-import org.spdx.html.LicenseHTMLFile;
-import org.spdx.html.LicenseTOCHTMLFile;
+import org.spdx.htmltemplates.LicenseHTMLFile;
+import org.spdx.htmltemplates.LicenseTOCHTMLFile;
import org.spdx.rdfparser.license.ListedLicenseException;
import org.spdx.rdfparser.license.SpdxListedLicense;
import org.spdx.licenselistpublisher.LicenseGeneratorException;
@@ -30,7 +30,7 @@
import com.github.mustachejava.MustacheException;
/**
- * @author gary
+ * @author Gary O'Neall
*
*/
public class LicenseRdfaFormatWriter implements ILicenseFormatWriter {
diff --git a/src/org/spdx/licenselistpublisher/licensegenerator/SpdxWebsiteFormatWriter.java b/src/org/spdx/licenselistpublisher/licensegenerator/SpdxWebsiteFormatWriter.java
index c3c6f32..72f7dde 100644
--- a/src/org/spdx/licenselistpublisher/licensegenerator/SpdxWebsiteFormatWriter.java
+++ b/src/org/spdx/licenselistpublisher/licensegenerator/SpdxWebsiteFormatWriter.java
@@ -18,14 +18,14 @@
import java.io.File;
import java.io.IOException;
-import org.spdx.html.ExceptionHtml;
-import org.spdx.html.ExceptionHtmlToc;
+import org.spdx.htmltemplates.ExceptionHtml;
+import org.spdx.htmltemplates.ExceptionHtmlToc;
import org.spdx.html.ExceptionTOCJSONFile;
import org.spdx.html.InvalidLicenseTemplateException;
import org.spdx.html.LicenseExceptionJSONFile;
-import org.spdx.html.LicenseHTMLFile;
+import org.spdx.htmltemplates.LicenseHTMLFile;
import org.spdx.html.LicenseJSONFile;
-import org.spdx.html.LicenseTOCHTMLFile;
+import org.spdx.htmltemplates.LicenseTOCHTMLFile;
import org.spdx.html.LicenseTOCJSONFile;
import org.spdx.rdfparser.InvalidSPDXAnalysisException;
import org.spdx.rdfparser.license.AnyLicenseInfo;
diff --git a/src/org/spdx/licensexml/ListedLicense.xsd b/src/org/spdx/licensexml/ListedLicense.xsd
index 3b291cf..c0525d5 100644
--- a/src/org/spdx/licensexml/ListedLicense.xsd
+++ b/src/org/spdx/licensexml/ListedLicense.xsd
@@ -1,23 +1,48 @@
-
+
- XML Schema for the SPDX Listed License input format. This format is intended for internal use
- of the SPDX legal team for representing licenses in the github source repository
- github.com/spdx/listed-license-XML. A separate format of the same licenses are available
- for application usage at github.com/spdx/license-list-data.
- Licensed under CC-BY-4.0.
-
+ SPDX License List XML Schema
+
+ This format is internal to the SPDX legal team and is subject to change. For stable output formats, see license-list-data.
+
+
+ SPDX-License-Identifier: CC0-1.0
+
+
-
+
+
+
+
+ SPDXLicenseCollection is the root element of SPDX license lists.
+
+
+
+
+
+
+
+ SPDXLicenseCollectionType collects a set of licenses and/or exceptions. The order in which child elements are listed is not significant.
+
+
+
+
+
+
+ ExceptionType is an exception to a license condition or additional permissions beyond those granted in a license. Exceptions are not standalone licenses, although the schem for LicenseType is very similar. See the LicenseType documentation for details on the attribute semantics.
+
+
+
+
@@ -29,46 +54,297 @@
+
+
+
+ LicenseType is a license. It does not represent exceptions, although the schema for ExceptionType is very similar.
+
+
+
+
-
-
-
+
+
+
+
+ notes contains unstructured notes about the license.
+
+
+
+
+
+
+
+
+ standardLicenseHeader is the license steward's recommended text for per-file license grants. Place this element within text when the license contains the recommended grant text (for example, in an appendix). Make standardLicenseHeader a sibling of text when the license does not contain the recommended grant text.
+
+
+
+
+
+
+
+
+ text is the license text as a standalone document.
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+ licenseId is the short identifier used in SPDX License Expressions.
+
+
+
+
+
+
+
+
+ isOsiApproved is true if and only if the license is approved by Open Source Initiative as listed here.
+
+
+
+
+
+
+
+
+ isDeprecated is true if and only if the short identifier has been superseded by another. See the deprecatedVersion documentation for more details.
+
+
+
+
+
+
+
+
+ name is the name of the license, as provided by the license steward. In the absence of an external license steward, the name is chosen by the SPDX legal team.
+
+
+
+
+
+
+
+
+ listVersionAdded is the version of the license list which first included the license. This impacts the portability of a license identifier, because identifiers introduced in a later version may not be supported by tooling which targets an earlier version.
+
+
+
+
+
+
+
+
+ deprecatedVersion is the version of the license list which first deprecated the license. SPDX authors are encouraged to upgrade to the most recent equivalent identifier supported by their tooling. Future major releases of the license list may remove deprecated entries completely, after which new tools may no longer be able to understand them.
+
+
+
+
+
+
+
+ crossRefsType is a set of URIs for the license or exception. When the license steward has a URI devoted to the license, it must be the first entry in crossRefsType. The order in which the other child elements are listed is not significant.
+
+
+
+
+
+
+
+
+ crossRef is a URI related to the license or exception. Two main types are supported: resources devoted to the license itself (either by the license steward or third parties) and examples of use in prominent projects. Dead links may be supplemented by archived replacements (e.g. through the Internet Archive).
+
+
+
+
+
+
+
+
+
+
+ obsoletedBysType is a wrapper for a set of obsoletedBy entries.
+
+
+
-
+
+
+
+
+
+ obsoletedByType represents a recommended replacement for license expressions containing a given license or exception. The algorithm for determining the recommended replacement in the context of a given license expression is:
+
+
+ Parse the license expression to extract the short identifiers.
+ Look up obsoletedBy entries for the short identifiers.
+ If any obsoletedBy has an expression attribute that matches the source, the value of that obsoletedBy is the recommended replacement for that expression. Otherwise, the value of the obsoletedBy without an expression attribute is the recommended replacement for the short identifier.
+
+
+ For example, the expression GPL-2.0+ WITH GCC-exception-2.0 could be parsed to either of the following short license identifiers:
+
+
+
+
+ GPL-2.0+, in which case there would be a single obsoletedBy with no expression attribute:
+
+
+ <obsoletedBy>GPL-2.0-or-later</obsoletedBy>
+
+
+ So the recommended replacement for GPL-2.0+ would be GPL-2.0-or-later.
+
+
+
+
+ GPL-2.0, in which case there would be two obsoletedBy elements:
+
+
+ <obsoletedBy>GPL-2.0-only</obsoletedBy>
+ <obsoletedBy expression="GPL-2.0+">GPL-2.0-or-later</obsoletedBy>
+
+
+ The element with expression="GPL-2.0+" matches the initial license expression, so the recommended replacement for GPL-2.0+ is GPL-2.0-or-later.
+
+
+
+
+
+
+
+
+
+ expression is the license expression which is obsoleted by the expression contained by the element. Defaults to the bare identifier.
+
+
+
+
+
-
-
-
+
+
+
+ altType represents alternative content, where the SPDX considers several alternatives legally equivalent. The match will support the legally equivalent alternatives. While the SPDX will aim to exclude legally-signicant differences in match, this is not always possible. Consumers are encouraged to review matched text manually and make their own conclusions about legal significance.
+
+
+
+
+
+
+
+ This formatted content (potentially empty) is the canonical text recommended by the SPDX. It should match at least one version of the canonical text currently recommended by the license steward, if any.
+
+
+
+
+
+
+
+
+ name is a unique (within the license/exception) name for this altType element.
+
+
+
+
+
+
+
+
+ match is the POSIX extended regular expression (ERE) defining allowed matches. Where possible, alternates are listed in order of decreasing numbers of matched characters, which allows for regular expression engines using both POSIX's longest-match semantics and those which prefer the leftmost branch (e.g. Go, JavaScript, Perl, Python, etc.)
+
+
+
+
+
+
+
+ optionalType is formatted text that is not legally significant. The legal meaning of the license/exception is the same regardless of whether the optional text is included or not.
+
+
+
+
+
+
+
+
+
+ listType formats a list of entries. We do not distinguish between ordered and unordered lists, because bullets must be declared explicitly in the formatted content.
+
+
+
-
+
+
+
+
+ listStandardLicenseHeaderType is a listType that also allows <standardLicenseHeader> within its ancestor elements.
+
+
+
+
+
+
+
+
+
+
+
+
+ emptyType is empty, for elements like <br/> that must contain no content.
+
+
+
+
+
+
+
+ formattedFixedTextType is formatted text without optional or variable portions.
+
+
+
+
+
+
+ formattedAltTextType is formatted text that allows optional and variable portions.
+
+
+
+
+
+
+
+
+
+ formatttedFixedTextGroup is formatted text without optional or variable portions. The children for formattedAltStandardLicenseHeaderTextGroup have the same semantics, except for the fixed/alt and standard license header distinctions. See the formattedAltStandardLicenseHeaderTextGroup documentation for details on the attribute semantics.
+
+
+
@@ -79,6 +355,13 @@
+
+
+
+ formatttedAltTextGroup is formatted text with optional and variable portions. The children for formattedAltStandardLicenseHeaderTextGroup have the same semantics, except for the standard license header distinction. See the formattedAltStandardLicenseHeaderTextGroup documentation for details on the attribute semantics.
+
+
+
@@ -90,4 +373,65 @@
-
+
+
+
+
+
+
+ p is a paragraph with the same semantics as in HTML.
+
+
+
+
+
+
+
+
+ bullet is a list-item bullet.
+
+
+
+
+
+
+
+
+
+
+
+ br is a line break with the same semantics as in HTML.
+
+
+
+
+
+
+
+
+ titleText is the title of the license/exception. This that the content should be formatted as a header and that it optional (as described in optionalType).
+
+
+
+
+
+
+
+
+ copyrightText is the content copyright statement. Some licenses/exceptions (e.g. the GPL family) include a copright line for the license/exception itself; copyrightText should not be used for those cases.
+
+
+
+
+
+
+
+
+ standardLicenseHeader is the license steward's recommended text for per-file license grants. Place this element within text when the license contains the recommended grant text (for example, in an appendix). Make standardLicenseHeader a sibling of text when the license does not contain the recommended grant text.
+
+
+
+
+
+
+
\ No newline at end of file