View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.tools.plugin.extractor.annotations.converter;
20  
21  import java.net.URI;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.Map;
27  import java.util.Optional;
28  import java.util.function.Function;
29  
30  import org.apache.maven.tools.plugin.javadoc.FullyQualifiedJavadocReference;
31  import org.apache.maven.tools.plugin.javadoc.FullyQualifiedJavadocReference.MemberType;
32  import org.apache.maven.tools.plugin.javadoc.JavadocLinkGenerator;
33  import org.apache.maven.tools.plugin.javadoc.JavadocReference;
34  
35  /**
36   * Simple converter not leveraging actual Java classes only for testing purposes.
37   * Only generates internal {@link FullyQualifiedJavadocReference}s.
38   *
39   */
40  public class SimpleConverterContext implements ConverterContext {
41  
42      private final String packageName;
43  
44      private final Collection<JavadocReference> unresolvableReferences;
45  
46      private final Function<FullyQualifiedJavadocReference, URI> urlSupplier;
47  
48      private final Map<String, Object> attributes;
49  
50      public SimpleConverterContext(String packageName, URI javadocBaseUrl, JavadocReference... unresolvableReferences) {
51          this(
52                  packageName,
53                  (ref) -> new JavadocLinkGenerator(javadocBaseUrl, "11").createLink(ref),
54                  unresolvableReferences);
55      }
56  
57      public SimpleConverterContext(
58              String packageName,
59              Function<FullyQualifiedJavadocReference, URI> urlSupplier,
60              JavadocReference... unresolvableReferences) {
61          super();
62          this.packageName = packageName;
63          this.unresolvableReferences = new ArrayList<>();
64          this.urlSupplier = urlSupplier;
65          if (unresolvableReferences != null) {
66              this.unresolvableReferences.addAll(Arrays.asList(unresolvableReferences));
67          }
68          attributes = new HashMap<>();
69      }
70  
71      @Override
72      public Optional<String> getModuleName() {
73          return Optional.empty();
74      }
75  
76      @Override
77      public String getPackageName() {
78          return packageName;
79      }
80  
81      @Override
82      public String getLocation() {
83          return "customlocation:0";
84      }
85  
86      @Override
87      public FullyQualifiedJavadocReference resolveReference(JavadocReference reference) {
88          if (unresolvableReferences.contains(reference)) {
89              throw new IllegalArgumentException("Unresolvable reference" + reference);
90          }
91          final String packageName;
92          final Optional<String> className;
93          if (reference.getPackageNameClassName().isPresent()) {
94              String packageNameClassName = reference.getPackageNameClassName().get();
95              // first character lowercase, assume package name
96              if (Character.isLowerCase(packageNameClassName.charAt(0))) {
97                  // find last "."
98                  int lastDotIndex = packageNameClassName.lastIndexOf('.'); // nested classes not supported
99                  if (Character.isUpperCase(packageNameClassName.charAt(lastDotIndex + 1))) {
100                     packageName = packageNameClassName.substring(0, lastDotIndex);
101                     className = Optional.of(packageNameClassName.substring(lastDotIndex + 1));
102                 } else {
103                     packageName = packageNameClassName;
104                     className = Optional.empty();
105                 }
106             } else {
107                 packageName = this.packageName;
108                 className = Optional.of(packageNameClassName);
109             }
110         } else {
111             className = Optional.empty();
112             packageName = this.packageName;
113         }
114         Optional<String> normalizedMember = reference.getMember();
115         MemberType memberType = null;
116         if (reference.getMember().isPresent()) {
117             String member = reference.getMember().get();
118             // normalize (i.e. strip argument names and whitespaces)
119             int indexOfOpeningParentheses = member.indexOf('(');
120             int indexOfClosingParentheses = member.indexOf(')');
121             if (indexOfOpeningParentheses >= 0 && indexOfClosingParentheses >= 0) {
122                 StringBuilder methodArguments = new StringBuilder("(");
123                 boolean isFirstArgument = true;
124                 for (String methodArgument : member.substring(indexOfOpeningParentheses + 1, indexOfClosingParentheses)
125                         .split("\\s*,\\s*")) {
126                     String argumentType;
127                     int indexOfSpace = methodArgument.indexOf(' ');
128                     if (indexOfSpace >= 0) {
129                         argumentType = methodArgument.substring(0, indexOfSpace);
130                     } else {
131                         argumentType = methodArgument;
132                     }
133                     if (isFirstArgument) {
134                         isFirstArgument = false;
135                     } else {
136                         methodArguments.append(',');
137                     }
138                     methodArguments.append(argumentType);
139                 }
140                 methodArguments.append(')');
141                 normalizedMember =
142                         Optional.of(member.substring(0, indexOfOpeningParentheses) + methodArguments.toString());
143                 memberType = MemberType.METHOD;
144             } else {
145                 memberType = MemberType.FIELD;
146             }
147         }
148         return new FullyQualifiedJavadocReference(
149                 packageName, className, normalizedMember, Optional.ofNullable(memberType), reference.getLabel(), false);
150     }
151 
152     @Override
153     public URI getUrl(FullyQualifiedJavadocReference reference) {
154         return urlSupplier.apply(reference);
155     }
156 
157     @Override
158     public boolean isReferencedBy(FullyQualifiedJavadocReference reference) {
159         return false;
160     }
161 
162     @Override
163     public String getStaticFieldValue(FullyQualifiedJavadocReference reference) {
164         return "some field value";
165     }
166 
167     @Override
168     public URI getInternalJavadocSiteBaseUrl() {
169         return URI.create("https://javadoc.example.com");
170     }
171 
172     @SuppressWarnings("unchecked")
173     @Override
174     public <T> T setAttribute(String name, T value) {
175         return (T) attributes.put(name, value);
176     }
177 
178     @SuppressWarnings("unchecked")
179     @Override
180     public <T> T getAttribute(String name, Class<T> clazz, T defaultValue) {
181         return (T) attributes.getOrDefault(name, defaultValue);
182     }
183 
184     @Override
185     public boolean canGetUrl() {
186         return true;
187     }
188 }