001/* 002 * JDrupes MDoclet 003 * Copyright 2013 Raffael Herzog 004 * Copyright (C) 2017 Michael N. Lipp 005 * 006 * This program is free software; you can redistribute it and/or modify it 007 * under the terms of the GNU General Public License as published by 008 * the Free Software Foundation; either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, but 012 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 013 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * for more details. 015 * 016 * You should have received a copy of the GNU General Public License along 017 * with this program; if not, see <http://www.gnu.org/licenses/>. 018 */ 019package org.jdrupes.mdoclet; 020 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024import java.util.regex.Matcher; 025import java.util.regex.Pattern; 026 027/** 028 * Utility class providing some helpers for working with tags. 029 */ 030public final class Tags { 031 032 /** 033 * The name of text tags in the resulting array of 034 * {@link com.sun.javadoc.Doc#inlineTags() Doc.inlineTags()}. 035 */ 036 public static final String TEXT_TAG_NAME = "Text"; 037 038 private static final Pattern TAG_RE = Pattern.compile("\\{@[^\\}]*\\}"); 039 private static final Pattern SUBST_RE = Pattern.compile("\\{@\\}"); 040 041 private static Map<String, String> KINDS = new HashMap<>(); 042 { 043 KINDS.put("@exception", "@throws"); 044 KINDS.put("@link", "@see"); 045 KINDS.put("@linkplain", "@see"); 046 KINDS.put("@serialData", "@serial"); 047 } 048 049 private Tags() { 050 } 051 052 /** 053 * Gets the {@link com.sun.javadoc.Tag#kind() kind} of the tag with the given name. 054 * Returns the original name if the tag is unknown. 055 * 056 * @param name The tag's name. 057 * 058 * @return The kind of the tag. 059 * 060 * @see com.sun.javadoc.Tag#kind() 061 */ 062 public static String kindOf(String name) { 063 String kind = KINDS.get(name); 064 return kind == null ? name : kind; 065 } 066 067 /** 068 * Extracts all inline tags from the given comment and saves them in a target list. 069 * 070 * **Example** 071 * 072 * ``` 073 * /** 074 * * Foo {{@literal @}link bar} bar. 075 * *{@literal /} 076 * ``` 077 * 078 * becomes 079 * 080 * ``` 081 * /** 082 * * Foo {{@literal @}} bar. 083 * *{@literal /} 084 * ``` 085 * 086 * and the target list contains the string `"{{@literal @}link bar}"`. 087 * 088 * @param comment The comment to extract the inline tags from. 089 * @param target The target list to save the extracted inline tags to. 090 * 091 * @return The comment with all inline tags replaced with `"{{@literal @}}"`. 092 * 093 * @see #insertInlineTags(String, java.util.List) 094 */ 095 public static String extractInlineTags(String comment, List<String> target) { 096 StringBuffer result = new StringBuffer(); 097 Matcher matcher = TAG_RE.matcher(comment); 098 while ( matcher.find() ) { 099 target.add(matcher.group()); 100 matcher.appendReplacement(result, "{@}"); 101 } 102 matcher.appendTail(result); 103 return result.toString(); 104 } 105 106 /** 107 * Re-inserts all inline tags previously extracted using 108 * {@link #extractInlineTags(String, java.util.List) extractInlineTags()}. All 109 * occurrences of `"{{@literal @}}"` will be replaced by the string at the 110 * corresponding index of the list. 111 * 112 * @param comment The comment text. 113 * @param tags The list of saved inline tags. 114 * 115 * @return The String with all inline tags re-inserted. 116 * 117 * @see #extractInlineTags(String, java.util.List) 118 */ 119 public static String insertInlineTags(String comment, List<String> tags) { 120 StringBuffer result = new StringBuffer(); 121 Matcher matcher = SUBST_RE.matcher(comment); 122 int index = 0; 123 while ( matcher.find() ) { 124 String tag; 125 if ( index < tags.size() ) { 126 tag = tags.get(index++); 127 } 128 else { 129 tag = "{@}"; 130 } 131 matcher.appendReplacement(result, Matcher.quoteReplacement(tag)); 132 } 133 matcher.appendTail(result); 134 return result.toString(); 135 } 136 137}