001package org.apache.maven.tools.plugin.extractor.annotations.converter.tag; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.util.Optional; 023import java.util.function.UnaryOperator; 024 025import org.apache.maven.tools.plugin.extractor.annotations.converter.ConverterContext; 026import org.apache.maven.tools.plugin.javadoc.FullyQualifiedJavadocReference; 027import org.apache.maven.tools.plugin.javadoc.JavadocReference; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031/** 032 * Utility methods for dealing with links generated from Javadoc tags. 033 */ 034public class LinkUtils 035{ 036 037 private static final Logger LOG = LoggerFactory.getLogger( LinkUtils.class ); 038 039 private LinkUtils() 040 { 041 // only static methods 042 } 043 044 public static String createLink( String referenceValue, ConverterContext context ) 045 { 046 return createLink( referenceValue, context, UnaryOperator.identity() ); 047 } 048 049 public static String createLink( String referenceValue, ConverterContext context, 050 UnaryOperator<String> labelDecorator ) 051 { 052 try 053 { 054 JavadocReference reference = JavadocReference.parse( referenceValue ); 055 FullyQualifiedJavadocReference fqReference = context.resolveReference( reference ); 056 if ( !context.canGetUrl() ) 057 { 058 return getReferenceLabel( fqReference, context, labelDecorator, "no javadoc sites associated" ); 059 } 060 return createLink( referenceValue, fqReference, context, labelDecorator ); 061 } 062 catch ( IllegalArgumentException e ) 063 { 064 LOG.warn( "Unresolvable link in javadoc tag with value {} found in {}: {}", referenceValue, 065 context.getLocation(), e.getMessage() ); 066 return labelDecorator.apply( referenceValue ) + "<!-- this link could not be resolved -->"; 067 } 068 } 069 070 private static String createLink( String referenceValue, FullyQualifiedJavadocReference fqReference, 071 ConverterContext context, UnaryOperator<String> labelDecorator ) 072 { 073 StringBuilder link = new StringBuilder(); 074 try 075 { 076 link.append( "<a href=\"" ); 077 link.append( context.getUrl( fqReference ).toString() ); 078 link.append( "\">" ); 079 String label = getReferenceLabel( fqReference, context ); 080 label = labelDecorator.apply( label ); 081 link.append( label ); 082 link.append( "</a>" ); 083 } 084 catch ( IllegalArgumentException e ) 085 { 086 LOG.warn( "Could not get javadoc URL for reference {} at {} (fully qualified {}): {}", referenceValue, 087 fqReference, context.getLocation(), e.getMessage() ); 088 return getReferenceLabel( fqReference, context, labelDecorator, 089 "reference not found in associated javadoc sites" ); 090 } 091 return link.toString(); 092 } 093 094 private static String getReferenceLabel( FullyQualifiedJavadocReference fqReference, ConverterContext context, 095 UnaryOperator<String> labelDecorator, String htmlComment ) 096 { 097 String label = getReferenceLabel( fqReference, context ); 098 return labelDecorator.apply( label ) + "<!-- " + htmlComment + " -->"; 099 } 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}