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/> &nbsp; &nbsp; target.{@link java.lang.Class#getName() getName}(), link, dbgDest_ifNonNull)</code>
041      <br/>Where the {@code link}'s url is
042      <br/> &nbsp; &nbsp; <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/> &nbsp; &nbsp; com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#direct(String, Object)({@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile(String) compile}(&quot;\\b&quot; + word_findWhat + &quot;\\b([ \\t]*\\()&quot;), link_rplcWith + &quot;$1&quot;).
064      <br/> &nbsp; &nbsp; {@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/> &nbsp; &nbsp; com.github.xbn.regexutil.z.RegexReplacer_CfgForNeeder#direct(String, Object)({@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile(String) compile}(&quot;\\b&quot; + word_findWhat + &quot;\\b&quot;), link_rplcWith).
077      <br/> &nbsp; &nbsp; {@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/> &nbsp; &nbsp; target.{@link java.lang.reflect.Method#getName() getName}(), link, dbgDest_ifNonNull)</code>
112      <br/>Where the {@code link}'s url is
113      <br/> &nbsp; &nbsp; <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/> &nbsp; &nbsp; <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}