blob: 3d8f1927e67d7120eb703130040a2087d59a407a [file]
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang=""><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>Licenses.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Creadur RAT::Core</a> &gt; <a href="index.source.html" class="el_package">org.apache.rat.help</a> &gt; <span class="el_source">Licenses.java</span></div><h1>Licenses.java</h1><pre class="source lang-java linenums">/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* &quot;License&quot;); 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
* &quot;AS IS&quot; 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.apache.rat.help;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.lang3.StringUtils;
import org.apache.rat.ConfigurationException;
import org.apache.rat.ReportConfiguration;
import org.apache.rat.analysis.IHeaderMatcher;
import org.apache.rat.config.parameters.ComponentType;
import org.apache.rat.config.parameters.Description;
import org.apache.rat.config.parameters.DescriptionBuilder;
import org.apache.rat.configuration.MatcherBuilderTracker;
import org.apache.rat.configuration.builders.AbstractBuilder;
import org.apache.rat.license.ILicense;
import org.apache.rat.license.ILicenseFamily;
import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
import static java.lang.String.format;
/**
* Generates text based documentation for Licenses, LicenceFamilies, and Matchers.
* Utilizes the same command line as the CLI based Report client so that additional licenses, etc. can be added.
*/
public final class Licenses extends AbstractHelp {
/** The report configuration to extract licenses from */
private final ReportConfiguration config;
/** The licenses in the report config */
private final SortedSet&lt;ILicense&gt; licenses;
/** The formatter */
private final HelpFormatter formatter;
/** The writer to write to */
private final PrintWriter printWriter;
/**
* Constructor
* @param config The configuration that contains the license information.
* @param writer the writer to write the report to.
*/
<span class="fc" id="L67"> public Licenses(final ReportConfiguration config, final Writer writer) {</span>
<span class="fc" id="L68"> this.config = config;</span>
<span class="fc" id="L69"> this.licenses = config.getLicenses(LicenseFilter.ALL);</span>
<span class="fc" id="L70"> printWriter = new PrintWriter(writer);</span>
<span class="fc" id="L71"> formatter = HelpFormatter.builder().setShowDeprecated(false).setPrintWriter(printWriter).get();</span>
<span class="fc" id="L72"> }</span>
/**
* Prints the text indented and wrapped.
* @param indent the number of spaces to indent.
* @param text the text to write.
*/
void print(final int indent, final String text) {
<span class="fc" id="L80"> int leftMargin = indent * HELP_PADDING;</span>
<span class="fc" id="L81"> int tabStop = leftMargin + (HELP_PADDING / 2);</span>
<span class="fc" id="L82"> formatter.printWrapped(printWriter, HELP_WIDTH, tabStop, createPadding(leftMargin) + text);</span>
<span class="fc" id="L83"> }</span>
/**
* Print the help text with the version information.
* @throws IOException on output error.
*/
public void printHelp() throws IOException {
<span class="fc" id="L90"> print(0, format(&quot;Listing of licenses for %s&quot;, versionInfo));</span>
<span class="fc" id="L91"> output();</span>
<span class="fc" id="L92"> }</span>
/**
* Output the License information without the version information.
* @throws IOException on error.
*/
public void output() throws IOException {
<span class="fc" id="L100"> print(0, header(&quot;LICENSES&quot;));</span>
<span class="pc bpc" id="L102" title="1 of 2 branches missed."> if (licenses.isEmpty()) {</span>
<span class="nc" id="L103"> print(0, &quot;No licenses defined&quot;);</span>
} else {
<span class="fc" id="L105"> Description licenseDescription = DescriptionBuilder.build(licenses.first());</span>
<span class="fc bfc" id="L106" title="All 2 branches covered."> Collection&lt;Description&gt; licenseParams = licenseDescription.filterChildren(d -&gt; d.getType() == ComponentType.PARAMETER);</span>
<span class="fc" id="L108"> print(0, format(&quot;Licenses have the following properties:%n&quot;));</span>
<span class="fc bfc" id="L110" title="All 2 branches covered."> for (Description param : licenseParams) {</span>
<span class="fc" id="L111"> print(1, format(&quot;%s: %s%n&quot;, param.getCommonName(), param.getDescription()));</span>
<span class="fc" id="L112"> }</span>
<span class="fc" id="L114"> print(0, format(&quot;%nThe defined licenses are:%n&quot;));</span>
<span class="fc bfc" id="L115" title="All 2 branches covered."> for (ILicense l : licenses) {</span>
<span class="fc" id="L116"> print(0, System.lineSeparator());</span>
<span class="fc" id="L117"> printObject(0, l);</span>
<span class="fc" id="L118"> }</span>
}
<span class="fc" id="L120"> print(0, header(&quot;DEFINED MATCHERS&quot;));</span>
<span class="fc" id="L121"> SortedSet&lt;Description&gt; matchers = new TreeSet&lt;&gt;(Comparator.comparing(Description::getCommonName));</span>
<span class="fc bfc" id="L122" title="All 2 branches covered."> for (Class&lt;? extends AbstractBuilder&gt; mClazz : MatcherBuilderTracker.instance().getClasses()) {</span>
try {
<span class="fc" id="L124"> AbstractBuilder builder = mClazz.getConstructor().newInstance();</span>
<span class="fc" id="L125"> matchers.add(builder.getDescription());</span>
<span class="nc" id="L126"> } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException</span>
| IllegalArgumentException | InvocationTargetException e) {
<span class="nc" id="L128"> throw new ConfigurationException(</span>
<span class="nc" id="L129"> format(&quot;Can not instantiate matcher builder %s &quot;, mClazz.getName()), e);</span>
<span class="fc" id="L130"> }</span>
<span class="fc" id="L131"> }</span>
<span class="fc bfc" id="L132" title="All 2 branches covered."> for (Description description : matchers) {</span>
<span class="fc" id="L133"> print(0, format(&quot;%n%s: %s%n&quot;, description.getCommonName(), description.getDescription()));</span>
<span class="fc bfc" id="L134" title="All 2 branches covered."> for (Description child : description.getChildren().values()) {</span>
<span class="fc bfc" id="L135" title="All 2 branches covered."> if (IHeaderMatcher.class.isAssignableFrom(child.getChildType())) {</span>
<span class="fc bfc" id="L136" title="All 2 branches covered."> if (child.isCollection()) {</span>
<span class="fc" id="L137"> print(2, &quot;Encloses multiple matchers&quot;);</span>
} else {
<span class="fc" id="L139"> print(2, &quot;Wraps a single matcher&quot;);</span>
}
} else {
<span class="fc bfc" id="L142" title="All 2 branches covered."> print(1, format(&quot;%s: %s%s&quot;, child.getCommonName(), child.isRequired() ? &quot;(required) &quot; : &quot;&quot;, child.getDescription()));</span>
}
<span class="fc" id="L144"> }</span>
<span class="fc" id="L145"> }</span>
<span class="fc" id="L147"> print(0, header(&quot;DEFINED FAMILIES&quot;));</span>
<span class="fc bfc" id="L148" title="All 2 branches covered."> for (ILicenseFamily family : config.getLicenseFamilies(LicenseFilter.ALL)) {</span>
<span class="fc" id="L149"> print(1, format(&quot;%s - %s%n&quot;, family.getFamilyCategory(), family.getFamilyName()));</span>
<span class="fc" id="L150"> }</span>
<span class="fc" id="L151"> printWriter.flush();</span>
<span class="fc" id="L152"> }</span>
/**
* Print the description of an object.
* @param indent the number of spaces to indent the print.
* @param object the object to print.
* @throws IOException on output error.
*/
private void printObject(final int indent, final Object object) throws IOException {
<span class="pc bpc" id="L161" title="1 of 2 branches missed."> if (object == null) {</span>
<span class="nc" id="L162"> return;</span>
}
<span class="fc" id="L164"> Description description = DescriptionBuilder.build(object);</span>
<span class="pc bpc" id="L165" title="1 of 2 branches missed."> if (description == null) {</span>
<span class="nc" id="L166"> print(indent, format(&quot;Unknown Object of class: %s%n&quot;, object.getClass().getName()));</span>
} else {
<span class="fc" id="L168"> print(indent, format(&quot;%s (%s)%n&quot;, description.getCommonName(), description.getDescription()));</span>
<span class="fc" id="L169"> printChildren(indent + 1, object, description.getChildren());</span>
}
<span class="fc" id="L171"> }</span>
/**
* Returns {@code true} if the string is a UUID.
* @param s the string to check.
* @return {@code true} if the string is a UUID.
*/
private boolean isUUID(final String s) {
try {
<span class="fc" id="L180"> UUID.fromString(s);</span>
<span class="fc" id="L181"> return true;</span>
<span class="fc" id="L182"> } catch (IllegalArgumentException expected) {</span>
<span class="fc" id="L183"> return false;</span>
}
}
/**
* Print the information for the children.
* @param indent the number of spaces to indent.
* @param parent the parent object.
* @param children the children of the parent.
* @throws IOException on write error.
*/
private void printChildren(final int indent, final Object parent, final Map&lt;String, Description&gt; children) throws IOException {
<span class="fc bfc" id="L195" title="All 2 branches covered."> for (Description d : children.values()) {</span>
<span class="pc bpc" id="L196" title="2 of 4 branches missed."> switch (d.getType()) {</span>
case PARAMETER:
<span class="fc bfc" id="L198" title="All 2 branches covered."> if (d.isCollection()) {</span>
<span class="fc" id="L199"> print(indent, format(&quot;%s: %n&quot;, d.getCommonName()));</span>
try {
<span class="fc" id="L201"> Collection&lt;?&gt; result = (Collection&lt;?&gt;) d.getter(parent.getClass()).invoke(parent);</span>
<span class="fc bfc" id="L202" title="All 2 branches covered."> for (Object o : result) {</span>
<span class="fc" id="L203"> printObject(indent + 1, o);</span>
<span class="fc" id="L204"> }</span>
<span class="fc" id="L205"> return;</span>
<span class="nc" id="L206"> } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {</span>
<span class="nc" id="L207"> throw new RuntimeException(e);</span>
}
}
<span class="fc bfc" id="L210" title="All 2 branches covered."> if (IHeaderMatcher.class.isAssignableFrom(d.getChildType())) {</span>
<span class="fc" id="L211"> print(indent, format(&quot;%s: %n&quot;, d.getCommonName()));</span>
// is a matcher.
try {
<span class="fc" id="L214"> Object matcher = d.getter(parent.getClass()).invoke(parent);</span>
<span class="fc" id="L215"> printObject(indent + 1, matcher);</span>
<span class="nc" id="L216"> } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {</span>
<span class="nc" id="L217"> throw new RuntimeException(e);</span>
<span class="fc" id="L218"> }</span>
} else {
<span class="fc" id="L220"> String txt = StringUtils.defaultIfBlank(d.getParamValue(parent), &quot;&quot;).replaceAll(&quot;\\s{2,}&quot;, &quot; &quot;);</span>
<span class="fc bfc" id="L221" title="All 6 branches covered."> if (!txt.isEmpty() &amp;&amp; !(d.getCommonName().equals(&quot;id&quot;) &amp;&amp; isUUID(txt))) {</span>
<span class="fc" id="L222"> print(indent, format(&quot;%s: %s%n&quot;, d.getCommonName(), txt.replaceAll(&quot;\\s{2,}&quot;, &quot; &quot;)));</span>
}
}
<span class="fc" id="L225"> break;</span>
case BUILD_PARAMETER:
case LICENSE:
// do nothing
<span class="fc" id="L229"> break;</span>
case MATCHER:
<span class="nc" id="L231"> printChildren(indent + 1, parent, d.getChildren());</span>
break;
}
<span class="fc" id="L234"> }</span>
<span class="fc" id="L235"> }</span>
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.14.202510111229</span></div></body></html>