001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.tools.plugin.extractor.annotations.converter; 020 021import javax.inject.Inject; 022import javax.inject.Named; 023import javax.inject.Singleton; 024 025import java.util.Map; 026import java.util.regex.Matcher; 027import java.util.regex.Pattern; 028 029import org.apache.maven.tools.plugin.extractor.annotations.converter.tag.JavadocTagToHtmlConverter; 030import org.apache.maven.tools.plugin.extractor.annotations.converter.tag.inline.JavadocInlineTagToHtmlConverter; 031import org.jsoup.Jsoup; 032import org.jsoup.nodes.Document; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036/** 037 * Replaces inline javadoc taglets by their according XHTML representation. 038 */ 039@Named 040@Singleton 041public class JavadocInlineTagsToXhtmlConverter { 042 private static final Logger LOG = LoggerFactory.getLogger(JavadocInlineTagsToXhtmlConverter.class); 043 044 private final Map<String, JavadocInlineTagToHtmlConverter> converters; 045 046 private static final Pattern INLINE_TAG_PATTERN = Pattern.compile("\\{@([^\\s]*)(?:\\s([^\\}]*))?\\}"); 047 private static final int GROUP_TAG_NAME = 1; 048 private static final int GROUP_REFERENCE = 2; 049 050 @Inject 051 public JavadocInlineTagsToXhtmlConverter(Map<String, JavadocInlineTagToHtmlConverter> converters) { 052 this.converters = converters; 053 } 054 055 /** 056 * Converts the given text containing arbitrarily many inline javadoc tags with their according HTML replacement. 057 * @param text 058 * @param context 059 * @return 060 */ 061 public String convert(String text, ConverterContext context) { 062 Matcher matcher = INLINE_TAG_PATTERN.matcher(text); 063 StringBuffer sb = new StringBuffer(); 064 while (matcher.find()) { 065 String tagName = matcher.group(GROUP_TAG_NAME); 066 JavadocTagToHtmlConverter converter = converters.get(tagName); 067 String patternReplacement; 068 if (converter == null) { 069 patternReplacement = matcher.group(0) + "<!-- unsupported tag '" + tagName + "' -->"; 070 LOG.warn("Found unsupported javadoc inline tag '{}' in {}", tagName, context.getLocation()); 071 } else { 072 try { 073 patternReplacement = converter.convert(matcher.group(GROUP_REFERENCE), context); 074 } catch (Throwable t) { 075 patternReplacement = matcher.group(0) + "<!-- error processing javadoc tag '" + tagName + "': " 076 + t.getMessage() + " -->"; // leave original javadoc in place 077 LOG.warn("Error converting javadoc inline tag '{}' in {}", tagName, context.getLocation(), t); 078 } 079 } 080 matcher.appendReplacement(sb, Matcher.quoteReplacement(patternReplacement)); 081 } 082 matcher.appendTail(sb); 083 return toXHTML(sb.toString()); 084 } 085 086 static String toXHTML(String bodySnippet) { 087 String html = "<html><head></head><body>" + bodySnippet + "</body>"; // make it a valid HTML document 088 final Document document = Jsoup.parse(html); 089 document.outputSettings().syntax(Document.OutputSettings.Syntax.xml); 090 return document.body().html(); 091 } 092}