View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.tools.plugin.extractor.annotations.converter;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.util.Map;
26  import java.util.regex.Matcher;
27  import java.util.regex.Pattern;
28  
29  import org.apache.maven.tools.plugin.extractor.annotations.converter.tag.JavadocTagToHtmlConverter;
30  import org.apache.maven.tools.plugin.extractor.annotations.converter.tag.inline.JavadocInlineTagToHtmlConverter;
31  import org.jsoup.Jsoup;
32  import org.jsoup.nodes.Document;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  /**
37   * Replaces inline javadoc taglets by their according XHTML representation.
38   */
39  @Named
40  @Singleton
41  public class JavadocInlineTagsToXhtmlConverter {
42      private static final Logger LOG = LoggerFactory.getLogger(JavadocInlineTagsToXhtmlConverter.class);
43  
44      private final Map<String, JavadocInlineTagToHtmlConverter> converters;
45  
46      private static final Pattern INLINE_TAG_PATTERN = Pattern.compile("\\{@([^\\s]*)(?:\\s([^\\}]*))?\\}");
47      private static final int GROUP_TAG_NAME = 1;
48      private static final int GROUP_REFERENCE = 2;
49  
50      @Inject
51      public JavadocInlineTagsToXhtmlConverter(Map<String, JavadocInlineTagToHtmlConverter> converters) {
52          this.converters = converters;
53      }
54  
55      /**
56       * Converts the given text containing arbitrarily many inline javadoc tags with their according HTML replacement.
57       * @param text
58       * @param context
59       * @return
60       */
61      public String convert(String text, ConverterContext context) {
62          Matcher matcher = INLINE_TAG_PATTERN.matcher(text);
63          StringBuffer sb = new StringBuffer();
64          while (matcher.find()) {
65              String tagName = matcher.group(GROUP_TAG_NAME);
66              JavadocTagToHtmlConverter converter = converters.get(tagName);
67              String patternReplacement;
68              if (converter == null) {
69                  patternReplacement = matcher.group(0) + "<!-- unsupported tag '" + tagName + "' -->";
70                  LOG.warn("Found unsupported javadoc inline tag '{}' in {}", tagName, context.getLocation());
71              } else {
72                  try {
73                      patternReplacement = converter.convert(matcher.group(GROUP_REFERENCE), context);
74                  } catch (Throwable t) {
75                      patternReplacement = matcher.group(0) + "<!-- error processing javadoc tag '" + tagName + "': "
76                              + t.getMessage() + " -->"; // leave original javadoc in place
77                      LOG.warn("Error converting javadoc inline tag '{}' in {}", tagName, context.getLocation(), t);
78                  }
79              }
80              matcher.appendReplacement(sb, Matcher.quoteReplacement(patternReplacement));
81          }
82          matcher.appendTail(sb);
83          return toXHTML(sb.toString());
84      }
85  
86      static String toXHTML(String bodySnippet) {
87          String html = "<html><head></head><body>" + bodySnippet + "</body>"; // make it a valid HTML document
88          final Document document = Jsoup.parse(html);
89          document.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
90          return document.body().html();
91      }
92  }