XmlElements.java
/*
* 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
* "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.apache.rat.report.xml;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.rat.VersionInfo;
import org.apache.rat.api.Document;
import org.apache.rat.api.MetaData;
import org.apache.rat.api.RatException;
import org.apache.rat.config.results.ClaimValidator;
import org.apache.rat.license.ILicense;
import org.apache.rat.report.claim.ClaimStatistic;
import org.apache.rat.report.xml.writer.XmlWriter;
import org.apache.rat.utils.CasedString;
/**
* Creates the elements in the XML report.
*/
public final class XmlElements {
private XmlElements() {
// do not instantiate
}
/**
* Converts an enum name to pascal case.
*
* @param name the attribute to normalize
* @return a pascal cased name.
*/
private static String normalizeName(final String name) {
CasedString casedName = new CasedString(CasedString.StringCase.SNAKE, name.toLowerCase(Locale.ROOT));
return casedName.toCase(CasedString.StringCase.PASCAL);
}
/**
* Create the RAT report element. Includes the timestamp and the version element.
* Does not close the report.
*
* @throws RatException on error
*/
public static void ratReport(final XmlWriter writer) throws RatException {
try {
writer.startElement(Elements.RAT_REPORT.elementName)
.attribute(Attributes.TIMESTAMP.attributeName(),
DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.format(Calendar.getInstance()));
version(writer);
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* Creates the version element with all version attributes populated. Closes the version element.
*
* @throws RatException on error
*/
public static void version(final XmlWriter writer) throws RatException {
VersionInfo versionInfo = new VersionInfo();
try {
writer.startElement(Elements.VERSION.elementName)
.attribute(Attributes.PRODUCT.attributeName(), versionInfo.getTitle())
.attribute(Attributes.VENDOR.attributeName(), versionInfo.getVendor())
.attribute(Attributes.VERSION.attributeName(), versionInfo.getVersion())
.closeElement();
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* Creates a license element. Closes the element before exit.
*
* @param license the license for the element.
* @param approved {@code true} if the license is approved.
* @throws RatException on error.
*/
public static void license(final XmlWriter writer, final ILicense license, final boolean approved) throws RatException {
try {
writer.startElement(Elements.LICENSE.elementName)
.attribute(Attributes.ID.attributeName(), license.getId())
.attribute(Attributes.NAME.attributeName(), license.getName())
.attribute(Attributes.APPROVAL.attributeName(), Boolean.toString(approved))
.attribute(Attributes.FAMILY.attributeName(), license.getLicenseFamily().getFamilyCategory());
if (StringUtils.isNotBlank(license.getNote())) {
writer.startElement(Elements.NOTES.elementName).cdata(license.getNote()).closeElement();
}
writer.closeElement();
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* Creates a document element with attributes. Does <strong>NOT</strong> close the document element.
*
* @param document the document to write.
* @throws RatException on error.
*/
public static void document(final XmlWriter writer, final Document document) throws RatException {
final MetaData metaData = document.getMetaData();
try {
writer.startElement(Elements.RESOURCE.elementName)
.attribute(Attributes.NAME.attributeName(), document.getName().localized("/"))
.attribute(Attributes.TYPE.attributeName(), metaData.getDocumentType().toString())
.attribute(Attributes.MEDIA_TYPE.attributeName(), metaData.getMediaType().toString());
if (Document.Type.STANDARD == metaData.getDocumentType() || metaData.hasCharset()) {
writer.attribute(Attributes.ENCODING.attributeName(), metaData.getCharset().displayName());
}
if (document.isIgnored()) {
writer.attribute(Attributes.IS_DIRECTORY.attributeName(), Boolean.toString(document.isDirectory()));
}
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* Creates a statistics element.
*
* @throws RatException on error.
*/
public static void statistics(final XmlWriter writer, final ClaimStatistic statistic, final ClaimValidator validator) throws RatException {
try {
writer.startElement(Elements.STATISTICS.elementName);
for (ClaimStatistic.Counter counter : ClaimStatistic.Counter.values()) {
int count = statistic.getCounter(counter);
XmlElements.statistic(writer, counter.displayName(), count, counter.getDescription(), validator.isValid(counter, count));
}
for (String category : statistic.getLicenseFamilyCategories()) {
XmlElements.licenseCategory(writer, category, statistic.getLicenseCategoryCount(category));
}
for (String category : statistic.getLicenseNames()) {
XmlElements.licenseName(writer, category, statistic.getLicenseNameCount(category));
}
for (Document.Type type : statistic.getDocumentTypes()) {
XmlElements.documentType(writer, type.name(), statistic.getCounter(type));
}
writer.closeElement();
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* Creates a statistic element. Closes the element before returning.
*
* @param name the name of the statistics element.
* @param count the count for the element.
* @param description description of this statistic.
* @param isOk if {@code true} the count is within limits.
* @throws RatException on error.
*/
public static void statistic(final XmlWriter writer, final String name, final int count, final String description, final boolean isOk) throws RatException {
try {
writer.startElement(Elements.STATISTIC.elementName)
.attribute(Attributes.NAME.attributeName(), name)
.attribute(Attributes.COUNT.attributeName(), Integer.toString(count))
.attribute(Attributes.APPROVAL.attributeName(), Boolean.toString(isOk))
.attribute(Attributes.DESCRIPTION.attributeName(), description)
.closeElement();
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* Creates a statistic element. Closes the element before returning.
*
* @param name the name of the statistics element.
* @param count the count for the element.
* @throws RatException on error.
*/
public static void licenseCategory(final XmlWriter writer, final String name, final int count) throws RatException {
try {
writer.startElement(Elements.LICENSE_CATEGORY.elementName)
.attribute(Attributes.NAME.attributeName(), name)
.attribute(Attributes.COUNT.attributeName(), Integer.toString(count))
.closeElement();
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* Creates a statistic element. Closes the element before returning.
*
* @param name the name of the statistics element.
* @param count the count for the element.
* @throws RatException on error.
*/
public static void licenseName(final XmlWriter writer, final String name, final int count) throws RatException {
try {
writer.startElement(Elements.LICENSE_NAME.elementName)
.attribute(Attributes.NAME.attributeName(), name)
.attribute(Attributes.COUNT.attributeName(), Integer.toString(count))
.closeElement();
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* Creates a document type element. Closes the element before returning.
*
* @param name the name of the document type element.
* @param count the count for the element.
* @throws RatException on error.
*/
public static void documentType(final XmlWriter writer, final String name, final int count) throws RatException {
try {
writer.startElement(Elements.DOCUMENT_TYPE.elementName)
.attribute(Attributes.NAME.attributeName(), name)
.attribute(Attributes.COUNT.attributeName(), Integer.toString(count))
.closeElement();
} catch (IOException e) {
throw new RatException(e);
}
}
/**
* The elements in the report.
*/
public enum Elements {
/**
* The start of the RAT report.
*/
RAT_REPORT("rat-report"),
/**
* The version of RAT being run.
*/
VERSION(),
/**
* A resource element.
*/
RESOURCE(),
/**
* A license element.
*/
LICENSE(),
/**
* A notes element.
*/
NOTES(),
/**
* A statistics element.
*/
STATISTICS(),
/**
* A statistic entry.
*/
STATISTIC(),
/**
* A license name entry.
*/
LICENSE_NAME(),
/**
* A license category entry.
*/
LICENSE_CATEGORY(),
/**
* A document type entry.
*/
DOCUMENT_TYPE();
/**
* The XML name for the element
*/
private final String elementName;
/**
* Constructor.
*
* @param elementName the XML name for the element.
*/
Elements(final String elementName) {
this.elementName = elementName;
}
Elements() {
this.elementName = normalizeName(name());
}
}
/**
* The attributes of elements in the report.
*/
public enum Attributes {
/**
* A timestamp.
*/
TIMESTAMP,
/**
* A version string.
*/
VERSION,
/**
* The product identifier.
*/
PRODUCT,
/**
* The vendor identifier.
*/
VENDOR,
/**
* The approval flag.
*/
APPROVAL,
/**
* The family category.
*/
FAMILY,
/**
* The document type.
*/
TYPE,
/**
* The id.
*/
ID,
/**
* The name.
*/
NAME,
/**
* A counter.
*/
COUNT,
/**
* A description.
*/
DESCRIPTION,
/**
* The media type for a document.
*/
MEDIA_TYPE,
/**
* The encoding for a text document.
*/
ENCODING,
/**
* Denotes a skipped directory.
*/
IS_DIRECTORY;
String attributeName() {
return normalizeName(this.name());
}
}
}