View Javadoc
1   package org.apache.maven.tools.plugin.extractor.annotations.converter.tag;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Optional;
23  import java.util.function.UnaryOperator;
24  
25  import org.apache.maven.tools.plugin.extractor.annotations.converter.ConverterContext;
26  import org.apache.maven.tools.plugin.javadoc.FullyQualifiedJavadocReference;
27  import org.apache.maven.tools.plugin.javadoc.JavadocReference;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  /**
32   * Utility methods for dealing with links generated from Javadoc tags.
33   */
34  public class LinkUtils
35  {
36  
37      private static final Logger LOG = LoggerFactory.getLogger( LinkUtils.class );
38  
39      private LinkUtils()
40      {
41          // only static methods
42      }
43  
44      public static String createLink( String referenceValue, ConverterContext context )
45      {
46          return createLink( referenceValue, context, UnaryOperator.identity() );
47      }
48  
49      public static String createLink( String referenceValue, ConverterContext context,
50                                       UnaryOperator<String> labelDecorator )
51      {
52          try
53          {
54              JavadocReference reference = JavadocReference.parse( referenceValue );
55              FullyQualifiedJavadocReference fqReference = context.resolveReference( reference );
56              if ( !context.canGetUrl() )
57              {
58                  return getReferenceLabel( fqReference, context, labelDecorator, "no javadoc sites associated" );
59              }
60              return createLink( referenceValue, fqReference, context, labelDecorator );
61          }
62          catch ( IllegalArgumentException e )
63          {
64              LOG.warn( "Unresolvable link in javadoc tag with value {} found in {}: {}", referenceValue,
65                        context.getLocation(), e.getMessage() );
66              return labelDecorator.apply( referenceValue ) + "<!-- this link could not be resolved -->";
67          }
68      }
69  
70      private static String createLink( String referenceValue, FullyQualifiedJavadocReference fqReference, 
71                                        ConverterContext context, UnaryOperator<String> labelDecorator )
72      {
73          StringBuilder link = new StringBuilder();
74          try
75          {
76              link.append( "<a href=\"" );
77              link.append( context.getUrl( fqReference ).toString() );
78              link.append( "\">" );
79              String label = getReferenceLabel( fqReference, context );
80              label = labelDecorator.apply( label );
81              link.append( label );
82              link.append( "</a>" );
83          }
84          catch ( IllegalArgumentException e )
85          {
86              LOG.warn( "Could not get javadoc URL for reference {} at {} (fully qualified {}): {}", referenceValue,
87                        fqReference, context.getLocation(), e.getMessage() );
88              return getReferenceLabel( fqReference, context, labelDecorator,
89                                        "reference not found in associated javadoc sites" );
90          }
91          return link.toString();
92      }
93  
94      private static String getReferenceLabel( FullyQualifiedJavadocReference fqReference, ConverterContext context,
95                                        UnaryOperator<String> labelDecorator, String htmlComment ) 
96      {
97          String label = getReferenceLabel( fqReference, context );
98          return labelDecorator.apply( label ) + "<!-- " + htmlComment + " -->";
99      }
100 
101     /**
102      * @return the undecorated label of the link
103      * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#JSWOR656"> javadoc: How
104      *      a Name Appears</a>
105      */
106     private static String getReferenceLabel( FullyQualifiedJavadocReference fqReference, ConverterContext context )
107     {
108         if ( fqReference.getLabel().isPresent() )
109         {
110             return fqReference.getLabel().get();
111         }
112         else
113         {
114             Optional<String> packageName;
115             Optional<String> moduleName;
116             Optional<String> className = fqReference.getClassName();
117             if ( Optional.of( context.getPackageName() ).equals( fqReference.getPackageName() )
118                 && context.getModuleName().equals( fqReference.getModuleName() ) )
119             {
120                 packageName = Optional.empty();
121                 moduleName = Optional.empty();
122                 if ( context.isReferencedBy( fqReference ) )
123                 {
124                     className = Optional.empty();
125                 }
126             }
127             else
128             {
129                 packageName = fqReference.getPackageName();
130                 moduleName = fqReference.getModuleName();
131             }
132             return createLabel( moduleName, packageName, className, fqReference.getMember() );
133         }
134     }
135 
136     private static String createLabel( Optional<String> moduleName, Optional<String> packageName,
137                                        Optional<String> className, Optional<String> member )
138     {
139         StringBuilder sb = new StringBuilder();
140         if ( packageName.isPresent() && !"java.lang".equals( packageName.get() ) )
141         {
142             sb.append( packageName.get() );
143         }
144         if ( className.isPresent() )
145         {
146             if ( sb.length() > 0 )
147             {
148                 sb.append( '.' );
149             }
150             sb.append( className.get() );
151         }
152         if ( member.isPresent() )
153         {
154             if ( sb.length() > 0 )
155             {
156                 sb.append( '.' );
157             }
158             sb.append( member.get() );
159         }
160         return sb.toString();
161     }
162 
163 }