001/*license*\ 002 Codelet: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com) 003 004 This software is dual-licensed under the: 005 - Lesser General Public License (LGPL) version 3.0 or, at your option, any later version; 006 - Apache Software License (ASL) version 2.0. 007 008 Either license may be applied at your discretion. More information may be found at 009 - http://en.wikipedia.org/wiki/Multi-licensing. 010 011 The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at: 012 - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 013 - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 014\*license*/ 015package com.github.aliteralmind.codelet.alter; 016 import com.github.aliteralmind.codelet.CodeletInstance; 017 import com.github.aliteralmind.codelet.util.JavaDocUtil; 018 import com.github.xbn.lang.CrashIfObject; 019 import com.github.xbn.regexutil.RegexReplacer; 020 import com.github.xbn.regexutil.z.RegexReplacer_Cfg; 021 import java.lang.reflect.Constructor; 022 import java.lang.reflect.Field; 023 import java.lang.reflect.Method; 024 import java.util.regex.Pattern; 025 import static com.github.aliteralmind.codelet.CodeletBaseConfig.*; 026/** 027 <p>Convenience functions for creating {@code com.github.xbn.regexutil.}{@link com.github.xbn.regexutil.RegexReplacer RegexReplacer}s that replace a class, constructor, function, or object name with a clickable JavaDoc link.</p> 028 029 @see com.github.aliteralmind.codelet.alter.NewJDLinkForWordOccuranceNum NewJDLinkForWordOccuranceNum 030 * @since 0.1.0 031 * @author Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <a href="http://codelet.aliteralmind.com">{@code http://codelet.aliteralmind.com}</a>, <a href="https://github.com/aliteralmind/codelet">{@code https://github.com/aliteralmind/codelet}</a> 032 **/ 033public class NewJavaDocLinkReplacerFor { 034 /** 035 <p>Changes a class name to a JavaDoc link.</p> 036 037 * @param instance May not be {@code null}. 038 * @param target May not be {@code null}. 039 * @return <code>{@link #newReplaceWordOnlyWith(String, String, Appendable) newReplaceWordOnlyWith}( 040 <br/> target.{@link java.lang.Class#getName() getName}(), link, dbgDest_ifNonNull)</code> 041 <br/>Where the {@code link}'s url is 042 <br/> <code>{@link com.github.aliteralmind.codelet.util.JavaDocUtil JavaDocUtil}.{@link com.github.aliteralmind.codelet.util.JavaDocUtil#getUrlToClass(String, Class) getUrlToClass}(instance.{@link CodeletInstance#getRelativeUrlToDocRoot() getRelativeUrlToDocRoot}(), target)</code> 043 <br/>and display is the class's {@linkplain java.lang.Class#getSimpleName() simple name}. 044 */ 045 public static final RegexReplacer cclass(CodeletInstance instance, Class target, Appendable dbgDest_ifNonNull) { 046 String link = null; 047 try { 048 link = "<A HREF=\"" + 049 JavaDocUtil.getUrlToClass( 050 getDocRootUrlToTargetClass(instance, target), 051 target) + 052 "\">" + target.getSimpleName() + "</a>"; 053 } catch(RuntimeException rx) { 054 CrashIfObject.nnull(instance, "instance", null); 055 throw CrashIfObject.nullOrReturnCause(target, "target", null, rx); 056 } 057 return newReplaceWordOnlyWith(target.getSimpleName(), link, dbgDest_ifNonNull); 058 } 059 /** 060 <p>A new replacer for replacing the first occurance of a whole word with a link.</p> 061 062 * @return <code>new {@link com.github.xbn.regexutil.z.RegexReplacer_Cfg#RegexReplacer_Cfg() RegexReplacer_Cfg}(). 063 <br/> com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#direct(String, Object)({@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile(String) compile}("\\b" + word_findWhat + "\\b([ \\t]*\\()"), link_rplcWith + "$1"). 064 <br/> {@link com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#debugTo(Appendable) debugTo}(dbgDest_ifNonNull).{@link com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#first() first}().{@link com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#build() build}()</code> 065 * @see #newReplaceWordOnlyWith(String, String, Appendable) newReplaceWordOnlyWith 066 */ 067 public static final RegexReplacer newReplaceCnstrFuncNameOpenParenWith(String word_findWhat, String link_rplcWith, Appendable dbgDest_ifNonNull) { 068 return new RegexReplacer_Cfg(). 069 direct(Pattern.compile("\\b" + word_findWhat + "\\b([ \\t]*\\()"), link_rplcWith + "$1"). 070 debugTo(dbgDest_ifNonNull).first().build(); 071 } 072 /** 073 <p>A new replacer for replacing the first occurance of a class or field name with a link.</p> 074 075 * @return <code>new {@link com.github.xbn.regexutil.z.RegexReplacer_Cfg#RegexReplacer_Cfg() RegexReplacer_Cfg}(). 076 <br/> com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#direct(String, Object)({@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile(String) compile}("\\b" + word_findWhat + "\\b"), link_rplcWith). 077 <br/> {@link com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#debugTo(Appendable) debugTo}(dbgDest_ifNonNull).{@link com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#first() first}().{@link com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#build() build}()</code> 078 * @see #newReplaceCnstrFuncNameOpenParenWith(String, String, Appendable) newReplaceCnstrFuncNameOpenParenWith 079 */ 080 public static final RegexReplacer newReplaceWordOnlyWith(String word_findWhat, String link_rplcWith, Appendable dbgDest_ifNonNull) { 081 return new RegexReplacer_Cfg(). 082 direct(Pattern.compile("\\b" + word_findWhat + "\\b"), link_rplcWith). 083 debugTo(dbgDest_ifNonNull).first().build(); 084 } 085 /** 086 <p>Changes a constructor name to a JavaDoc link.</p> 087 */ 088 public static final RegexReplacer constructor(CodeletInstance instance, Constructor<?> target, Appendable dbgDest_ifNonNull) { 089 String className = null; 090 String link = null; 091 try { 092 className = target.getDeclaringClass().getSimpleName(); 093 link = "<A HREF=\"" + 094 JavaDocUtil.getUrlToConstructor( 095 getDocRootUrlToTargetClass(instance, target.getDeclaringClass()), 096 target) + 097 "\">" + className + "</a>"; 098 } catch(RuntimeException rx) { 099 CrashIfObject.nnull(instance, "instance", null); 100 throw CrashIfObject.nullOrReturnCause(target, "target", null, rx); 101 } 102 return newReplaceCnstrFuncNameOpenParenWith( 103 className, link, dbgDest_ifNonNull); 104 } 105 /** 106 <p>Changes a function name to a JavaDoc link.</p> 107 108 * @param instance May not be {@code null}. 109 * @param target May not be {@code null}. 110 * @return <code>{@link #newReplaceCnstrFuncNameOpenParenWith(String, String, Appendable) newReplaceCnstrFuncNameOpenParenWith}( 111 <br/> target.{@link java.lang.reflect.Method#getName() getName}(), link, dbgDest_ifNonNull)</code> 112 <br/>Where the {@code link}'s url is 113 <br/> <code>{@link com.github.aliteralmind.codelet.util.JavaDocUtil JavaDocUtil}.{@link com.github.aliteralmind.codelet.util.JavaDocUtil#getUrlToMethod(String, Method) getUrlToMethod}(instance.{@link CodeletInstance#getRelativeUrlToDocRoot() getRelativeUrlToDocRoot}(), target)</code> 114 <br/>and display is the method's name. 115 */ 116 public static final RegexReplacer method(CodeletInstance instance, Method target, Appendable dbgDest_ifNonNull) { 117 String link = null; 118 try { 119 link = "<A HREF=\"" + 120 JavaDocUtil.getUrlToMethod( 121 getDocRootUrlToTargetClass(instance, target.getDeclaringClass()), 122 target) + 123 "\">" + target.getName() + "</a>"; 124 } catch(RuntimeException rx) { 125 CrashIfObject.nnull(instance, "instance", null); 126 throw CrashIfObject.nullOrReturnCause(target, "target", null, rx); 127 } 128 return newReplaceCnstrFuncNameOpenParenWith( 129 target.getName(), link, dbgDest_ifNonNull); 130 } 131 /** 132 <p>Changes a field name (an object existing in another class) to a JavaDoc link.</p> 133 134 * @param instance May not be {@code null}. 135 * @param target May not be {@code null}. 136 * @return <code>{@link #newReplaceWordOnlyWith(String, String, Appendable) newReplaceWordOnlyWith}(target.{@link java.lang.reflect.Field#getName() getName}(), link, dbgDest_ifNonNull)</code> 137 <br/>Where the {@code link}'s url is 138 <br/> <code>{@link com.github.aliteralmind.codelet.util.JavaDocUtil JavaDocUtil}.{@link com.github.aliteralmind.codelet.util.JavaDocUtil#getUrlToField(String, Field) getUrlToField}(instance.{@link CodeletInstance#getRelativeUrlToDocRoot() getRelativeUrlToDocRoot}(), target)</code> 139 <br/>and display is the field's name. 140 */ 141 public static final RegexReplacer field(CodeletInstance instance, Field target, Appendable dbgDest_ifNonNull) { 142 String link = null; 143 try { 144 link = "<A HREF=\"" + 145 JavaDocUtil.getUrlToField( 146 getDocRootUrlToTargetClass(instance, target.getDeclaringClass()), 147 target) + 148 "#" + target.getName() + "\">" + 149 target.getName() + "</a>"; 150 } catch(RuntimeException rx) { 151 CrashIfObject.nnull(instance, "instance", null); 152 throw CrashIfObject.nullOrReturnCause(target, "target", null, rx); 153 } 154 return newReplaceWordOnlyWith(target.getName(), link, dbgDest_ifNonNull); 155 } 156 private NewJavaDocLinkReplacerFor() { 157 throw new IllegalStateException("Do not instantiate"); 158 } 159 /** 160 <p>Get the {@code {@docRoot}} url for a package, which may be internal or {@linkplain com.github.aliteralmind.codelet.CodeletBootstrap#EXTERNAL_DOC_ROOT_URL_FILE external}.</p> 161 162 * @param instance May not be {@code null}. 163 * @param target The class being linked to. May not be {@code null}, and must be in a package (<code>target.{@link java.lang.Class#getPackage() getPackage}().{@link java.lang.Package#getName() getName}()</code> must be non-empty). 164 * @return If <code>{@link com.github.aliteralmind.codelet.CodeletBaseConfig}.{@link com.github.aliteralmind.codelet.CodeletBaseConfig#getAllJavaDocRoots() getAllJavaDocRoots}().{@link com.github.aliteralmind.codelet.util.AllOnlineOfflineDocRoots#getPkgToUrlMap() getPkgToUrlMap}().{@link java.util.Map#get(Object) get}(target.{@link java.lang.Class#getPackage() getPackage}().{@link java.lang.Package#getName() getName}())</code> is<ul> 165 <li>non-{@code null}: The value returned from the map.</li> 166 <li>{@code null}: <code>instance.{@link CodeletInstance#getRelativeUrlToDocRoot() getRelativeUrlToDocRoot}()</code></li> 167 </ul> 168 */ 169 public static final String getDocRootUrlToTargetClass(CodeletInstance instance, Class<?> target) { 170 String pkgName = null; 171 try { 172 pkgName = target.getPackage().getName(); 173 } catch(RuntimeException rx) { 174 throw CrashIfObject.nullOrReturnCause(target, "target", null, rx); 175 } 176 if(pkgName.length() == 0) { 177 throw new IllegalArgumentException("target class has no package: " + target.getName()); 178 } 179 String url = getAllJavaDocRoots().getPkgToUrlMap().get(pkgName); 180 return ((url != null) ? url : instance.getRelativeUrlToDocRoot()); 181 } 182}