org.spdx.licenseTemplate.SpdxLicenseTemplateHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.spdx.licenseTemplate.SpdxLicenseTemplateHelper.java

Source

/**
 * Copyright (c) 2013 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.licenseTemplate;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringEscapeUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.spdx.rdfparser.license.LicenseParserException;

/**
 * Implements common conversion methods for processing SPDX license templates
 * @author Gary O'Neall
 *
 */
public class SpdxLicenseTemplateHelper {

    static final String START_RULE = "<<";
    static final String END_RULE = ">>";
    public static final Pattern RULE_PATTERN = Pattern
            .compile(START_RULE + "\\s*((beginOptional|endOptional|var)(.|\\s)*?)\\s*" + END_RULE);
    private static final int SPACES_PER_TAB = 5;
    private static final int MAX_TABS = 4;
    private static final int[] PIXELS_PER_TAB = new int[] { 20, 40, 60, 70 };

    /**
     * Parses the license template calling the templateOutputHandler for any text and rules found
     * @param licenseTemplate License template to be parsed
     * @param templateOutputHandler Handles the text, optional text, and variable rules text found
     * @throws LicenseParserException 
     */
    public static void parseTemplate(String licenseTemplate, ILicenseTemplateOutputHandler templateOutputHandler)
            throws LicenseTemplateRuleException, LicenseParserException {
        Matcher ruleMatcher = RULE_PATTERN.matcher(licenseTemplate);
        int end = 0;
        int optionalNestLevel = 0;
        while (ruleMatcher.find()) {
            // copy everything up to the start of the find
            String upToTheFind = licenseTemplate.substring(end, ruleMatcher.start());
            if (!upToTheFind.trim().isEmpty()) {
                templateOutputHandler.text(upToTheFind);
            }
            end = ruleMatcher.end();
            String ruleString = ruleMatcher.group(1);
            LicenseTemplateRule rule = new LicenseTemplateRule(ruleString);
            if (rule.getType() == LicenseTemplateRule.RuleType.VARIABLE) {
                templateOutputHandler.variableRule(rule);
            } else if (rule.getType() == LicenseTemplateRule.RuleType.BEGIN_OPTIONAL) {
                templateOutputHandler.beginOptional(rule);
                optionalNestLevel++;
            } else if (rule.getType() == LicenseTemplateRule.RuleType.END_OPTIONAL) {
                optionalNestLevel--;
                if (optionalNestLevel < 0) {
                    throw (new LicenseTemplateRuleException(
                            "End optional rule found without a matching begin optional rule after text '"
                                    + upToTheFind + "'"));
                }
                templateOutputHandler.endOptional(rule);
            } else {
                throw (new LicenseTemplateRuleException(
                        "Unrecognized rule: " + rule.getType().toString() + " after text '" + upToTheFind + "'"));
            }
        }
        if (optionalNestLevel > 0) {
            throw (new LicenseTemplateRuleException("Missing EndOptional rule and end of text"));
        }
        // copy the rest of the template to the end
        String restOfTemplate = licenseTemplate.substring(end);
        if (!restOfTemplate.isEmpty()) {
            templateOutputHandler.text(restOfTemplate);
        }
        templateOutputHandler.completeParsing();
    }

    /**
     * Converts a license template string to formatted HTML which highlights any 
     * rules or tags
     * @param licenseTemplate
     * @return
     * @throws LicenseTemplateRuleException 
     * @throws LicenseParserException 
     */
    public static String templateTextToHtml(String licenseTemplate) throws LicenseTemplateRuleException {
        HtmlTemplateOutputHandler htmlOutput = new HtmlTemplateOutputHandler();
        try {
            parseTemplate(licenseTemplate, htmlOutput);
        } catch (LicenseParserException e) {
            throw new LicenseTemplateRuleException("Parsing error parsing license template", e);
        }
        return htmlOutput.getHtml();
    }

    /**
     * Converts template text to standard default text using any default parameters in the rules
     * @param template
     * @return
     * @throws LicenseTemplateRuleException 
     * @throws LicenseParserException 
     */
    public static String templateToText(String template) throws LicenseTemplateRuleException {
        TextTemplateOutputHandler textOutput = new TextTemplateOutputHandler();
        try {
            parseTemplate(template, textOutput);
        } catch (LicenseParserException e) {
            throw new LicenseTemplateRuleException("Parsing error parsing license template", e);
        }
        return textOutput.getText();
    }

    /**
     * Escapes and formats text
     * @param text unformatted text
     * @return
     */
    public static String formatEscapeHTML(String text) {
        return formatEscapeHTML(text, false);
    }

    /**
     * Escapes and formats text
     * @param text unformatted text
     * @param inParagraph true if inside a paragraph tag
     * @return
     */
    public static String formatEscapeHTML(String text, boolean inParagraph) {
        String retval = StringEscapeUtils.escapeXml(text);
        return addHtmlFormatting(retval, inParagraph);
    }

    /**
     * Adds HTML formatting <br> and <p>
     * @param text unformatted text
     * @return
     */
    public static String addHtmlFormatting(String text) {
        return addHtmlFormatting(text, false);
    }

    /**
     * Adds HTML formatting <br> and <p>
     * @param text unformatted text
     * @param inParagraph true if inside a paragraph tag
     * @return
     */
    public static String addHtmlFormatting(String text, boolean inParagraph) {
        String[] lines = text.split("\n");
        StringBuilder result = new StringBuilder();
        result.append(lines[0]);
        int i = 1;
        while (i < lines.length) {
            if (lines[i].trim().isEmpty()) {
                // paragraph boundary 
                if (inParagraph) {
                    result.append("</p>");
                }
                result.append("\n");
                i++;
                if (i < lines.length) {
                    String paragraphTag = getParagraphTagConsideringTags(lines[i]);
                    result.append(paragraphTag);
                    result.append(lines[i++]);
                } else {
                    result.append("<p>");
                }
                inParagraph = true;
            } else {
                // just a line break
                result.append("<br/>");
                result.append("\n");
                result.append(lines[i++]);
            }
        }
        if (inParagraph) {
            result.append("</p>");
        } else if (text.endsWith("\n")) {
            result.append("<br/>\n");
        }
        return result.toString();
    }

    /**
     * Creating a paragraph tag and add the correct margin considering the number of spaces or tabs
     * @param string
     * @return
     */
    private static String getParagraphTagConsideringTags(String line) {
        int numSpaces = countLeadingSpaces(line);
        StringBuilder result = new StringBuilder();
        if (numSpaces >= SPACES_PER_TAB) {
            int numTabs = numSpaces / SPACES_PER_TAB;
            if (numTabs > MAX_TABS) {
                numTabs = MAX_TABS;
            }

            int pixels = PIXELS_PER_TAB[numTabs - 1];
            result.append("<p style=\"margin-left: ");
            result.append(String.valueOf(pixels));
            result.append("px;\">");
        } else {
            result.append("<p>");
        }
        return result.toString();
    }

    /**
     * Counts the number of leading spaces in a given line
     * @param string
     * @return
     */
    private static int countLeadingSpaces(String string) {
        char[] charArray = string.toCharArray();
        int retval = 0;
        while (retval < charArray.length && charArray[retval] == ' ') {
            retval++;
        }
        return retval;
    }

    /**
     * Converts an HTML string to text preserving line breaks for <br/> tags
     * @param html
     * @return
     */
    public static String htmlToText(String html) {
        String newlineString = "NewLineGoesHere";
        String replaceBrs = html.replaceAll("(?i)<br[^>]*>", newlineString);
        String replaceBrsAndPs = replaceBrs.replaceAll("(?i)<p[^>]*>", newlineString);
        Document doc = Jsoup.parse(replaceBrsAndPs);
        String retval = doc.text();
        retval = retval.replace(newlineString, "\n");
        return retval;
    }

}