1 /* 2 * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.javadoc.internal.doclets.formats.html; 27 28 import java.util.EnumMap; 29 import java.util.Objects; 30 import java.util.regex.Matcher; 31 import java.util.regex.Pattern; 32 33 import jdk.javadoc.internal.doclets.formats.html.markup.Comment; 34 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; 35 import jdk.javadoc.internal.doclets.formats.html.markup.Entity; 36 import jdk.javadoc.internal.doclets.formats.html.markup.FixedStringContent; 37 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 38 import jdk.javadoc.internal.doclets.toolkit.Content; 39 import jdk.javadoc.internal.doclets.toolkit.Resources; 40 import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; 41 import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable; 42 43 44 /** 45 * Constants and factory methods for common fragments of content 46 * used by HtmlDoclet. The string content of these fragments is 47 * generally obtained from the {@link Resources resources} found 48 * in the doclet's configuration. 49 * 50 * @implNote 51 * Many constants are made available in this class, so that they are 52 * only created once per doclet-instance, instead of once per generated page. 53 */ 54 public class Contents { 55 56 public final Content allClassesLabel; 57 public final Content allImplementedInterfacesLabel; 58 public final Content allModulesLabel; 59 public final Content allPackagesLabel; 60 public final Content allSuperinterfacesLabel; 61 public final Content also; 62 public final Content annotationTypeOptionalMemberLabel; 63 public final Content annotationTypeRequiredMemberLabel; 64 public final Content annotateTypeOptionalMemberSummaryLabel; 65 public final Content annotateTypeRequiredMemberSummaryLabel; 66 public final Content annotationType; 67 public final Content annotationTypeDetailsLabel; 68 public final Content annotationTypeMemberDetail; 69 public final Content annotationtypes; 70 public final Content annotationTypes; 71 public final Content classLabel; 72 public final Content classes; 73 public final Content constantFieldLabel; 74 public final Content constantsSummaryTitle; 75 public final Content constructorLabel; 76 public final Content constructorDetailsLabel; 77 public final Content constructorSummaryLabel; 78 public final Content constructors; 79 public final Content contentsHeading; 80 public final Content defaultPackageLabel; 81 public final Content default_; 82 public final Content deprecatedAPI; 83 public final Content deprecatedLabel; 84 public final Content deprecatedPhrase; 85 public final Content deprecatedForRemovalPhrase; 86 public final Content descfrmClassLabel; 87 public final Content descfrmInterfaceLabel; 88 public final Content descriptionLabel; 89 public final Content detailLabel; 90 public final Content enclosingClassLabel; 91 public final Content enclosingInterfaceLabel; 92 public final Content enumConstantLabel; 93 public final Content enumConstantDetailLabel; 94 public final Content enumConstantSummary; 95 public final Content enum_; 96 public final Content enums; 97 public final Content error; 98 public final Content errors; 99 public final Content exception; 100 public final Content exceptions; 101 public final Content exportedTo; 102 public final Content fieldLabel; 103 public final Content fieldDetailsLabel; 104 public final Content fieldSummaryLabel; 105 public final Content fields; 106 public final Content framesLabel; 107 public final Content fromLabel; 108 public final Content functionalInterface; 109 public final Content functionalInterfaceMessage; 110 public final Content helpLabel; 111 public final Content hierarchyForAllPackages; 112 public final Content implementation; 113 public final Content implementingClassesLabel; 114 public final Content inClass; 115 public final Content inInterface; 116 public final Content indexLabel; 117 public final Content interfaceLabel; 118 public final Content interfaces; 119 public final Content methodDetailLabel; 120 public final Content methodLabel; 121 public final Content methodSummary; 122 public final Content methods; 123 public final Content modifierAndTypeLabel; 124 public final Content modifierLabel; 125 public final Content moduleLabel; 126 public final Content module_; 127 public final Content moduleSubNavLabel; 128 public final Content modulesLabel; 129 public final Content navAnnotationTypeMember; 130 public final Content navAnnotationTypeOptionalMember; 131 public final Content navAnnotationTypeRequiredMember; 132 public final Content navConstructor; 133 public final Content navEnum; 134 public final Content navField; 135 public final Content navMethod; 136 public final Content navModuleDescription; 137 public final Content navModules; 138 public final Content navNested; 139 public final Content navPackages; 140 public final Content navProperty; 141 public final Content navServices; 142 public final Content nestedClassSummary; 143 public final Content newPage; 144 public final Content noFramesLabel; 145 public final Content noScriptMessage; 146 public final Content openModuleLabel; 147 public final Content openedTo; 148 public final Content overridesLabel; 149 public final Content overviewLabel; 150 public final Content packageHierarchies; 151 public final Content packageLabel; 152 public final Content package_; 153 public final Content packagesLabel; 154 public final Content properties; 155 public final Content propertyLabel; 156 public final Content propertyDetailsLabel; 157 public final Content propertySummaryLabel; 158 public final Content seeLabel; 159 public final Content serializedForm; 160 public final Content servicesLabel; 161 public final Content specifiedByLabel; 162 public final Content subclassesLabel; 163 public final Content subinterfacesLabel; 164 public final Content summaryLabel; 165 public final Content treeLabel; 166 public final Content typeLabel; 167 public final Content useLabel; 168 public final Content valueLabel; 169 170 private final EnumMap<VisibleMemberTable.Kind, Content> navLinkLabels; 171 172 private final Resources resources; 173 174 /** 175 * Creates a {@code Contents} object. 176 * 177 * @param configuration the configuration in which to find the 178 * resources used to look up resource keys, and other details. 179 */ 180 Contents(HtmlConfiguration configuration) { 181 this.resources = configuration.getResources(); 182 183 allClassesLabel = getNonBreakContent("doclet.All_Classes"); 184 allImplementedInterfacesLabel = getContent("doclet.All_Implemented_Interfaces"); 185 allModulesLabel = getNonBreakContent("doclet.All_Modules"); 186 allPackagesLabel = getNonBreakContent("doclet.All_Packages"); 187 allSuperinterfacesLabel = getContent("doclet.All_Superinterfaces"); 188 also = getContent("doclet.also"); 189 annotationTypeOptionalMemberLabel = getContent("doclet.Annotation_Type_Optional_Member"); 190 annotationTypeRequiredMemberLabel = getContent("doclet.Annotation_Type_Required_Member"); 191 annotateTypeOptionalMemberSummaryLabel = getContent("doclet.Annotation_Type_Optional_Member_Summary"); 192 annotateTypeRequiredMemberSummaryLabel = getContent("doclet.Annotation_Type_Required_Member_Summary"); 193 annotationType = getContent("doclet.AnnotationType"); 194 annotationTypeDetailsLabel = getContent("doclet.Annotation_Type_Member_Detail"); 195 annotationTypeMemberDetail = getContent("doclet.Annotation_Type_Member_Detail"); 196 annotationTypes = getContent("doclet.AnnotationTypes"); 197 annotationtypes = getContent("doclet.annotationtypes"); 198 classLabel = getContent("doclet.Class"); 199 classes = getContent("doclet.Classes"); 200 constantFieldLabel = getContent("doclet.ConstantField"); 201 constantsSummaryTitle = getContent("doclet.Constants_Summary"); 202 constructorLabel = getContent("doclet.Constructor"); 203 constructorDetailsLabel = getContent("doclet.Constructor_Detail"); 204 constructorSummaryLabel = getContent("doclet.Constructor_Summary"); 205 constructors = getContent("doclet.Constructors"); 206 contentsHeading = getContent("doclet.Contents"); 207 defaultPackageLabel = new StringContent(DocletConstants.DEFAULT_PACKAGE_NAME); 208 default_ = getContent("doclet.Default"); 209 deprecatedAPI = getContent("doclet.Deprecated_API"); 210 deprecatedLabel = getContent("doclet.navDeprecated"); 211 deprecatedPhrase = getContent("doclet.Deprecated"); 212 deprecatedForRemovalPhrase = getContent("doclet.DeprecatedForRemoval"); 213 descfrmClassLabel = getContent("doclet.Description_From_Class"); 214 descfrmInterfaceLabel = getContent("doclet.Description_From_Interface"); 215 descriptionLabel = getContent("doclet.Description"); 216 detailLabel = getContent("doclet.Detail"); 217 enclosingClassLabel = getContent("doclet.Enclosing_Class"); 218 enclosingInterfaceLabel = getContent("doclet.Enclosing_Interface"); 219 enumConstantLabel = getContent("doclet.Enum_Constant"); 220 enumConstantDetailLabel = getContent("doclet.Enum_Constant_Detail"); 221 enumConstantSummary = getContent("doclet.Enum_Constant_Summary"); 222 enum_ = getContent("doclet.Enum"); 223 enums = getContent("doclet.Enums"); 224 error = getContent("doclet.Error"); 225 errors = getContent("doclet.Errors"); 226 exception = getContent("doclet.Exception"); 227 exceptions = getContent("doclet.Exceptions"); 228 exportedTo = getContent("doclet.ExportedTo"); 229 fieldDetailsLabel = getContent("doclet.Field_Detail"); 230 fieldSummaryLabel = getContent("doclet.Field_Summary"); 231 fieldLabel = getContent("doclet.Field"); 232 fields = getContent("doclet.Fields"); 233 framesLabel = getContent("doclet.Frames"); 234 fromLabel = getContent("doclet.From"); 235 functionalInterface = getContent("doclet.Functional_Interface"); 236 functionalInterfaceMessage = getContent("doclet.Functional_Interface_Message"); 237 helpLabel = getContent("doclet.Help"); 238 hierarchyForAllPackages = getContent("doclet.Hierarchy_For_All_Packages"); 239 implementation = getContent("doclet.Implementation"); 240 implementingClassesLabel = getContent("doclet.Implementing_Classes"); 241 inClass = getContent("doclet.in_class"); 242 inInterface = getContent("doclet.in_interface"); 243 indexLabel = getContent("doclet.Index"); 244 interfaceLabel = getContent("doclet.Interface"); 245 interfaces = getContent("doclet.Interfaces"); 246 methodDetailLabel = getContent("doclet.Method_Detail"); 247 methodSummary = getContent("doclet.Method_Summary"); 248 methodLabel = getContent("doclet.Method"); 249 methods = getContent("doclet.Methods"); 250 modifierLabel = getContent("doclet.Modifier"); 251 modifierAndTypeLabel = getContent("doclet.Modifier_and_Type"); 252 moduleLabel = getContent("doclet.Module"); 253 module_ = getContent("doclet.module"); 254 moduleSubNavLabel = getContent("doclet.Module_Sub_Nav"); 255 modulesLabel = getContent("doclet.Modules"); 256 navAnnotationTypeMember = getContent("doclet.navAnnotationTypeMember"); 257 navAnnotationTypeOptionalMember = getContent("doclet.navAnnotationTypeOptionalMember"); 258 navAnnotationTypeRequiredMember = getContent("doclet.navAnnotationTypeRequiredMember"); 259 navConstructor = getContent("doclet.navConstructor"); 260 navEnum = getContent("doclet.navEnum"); 261 navField = getContent("doclet.navField"); 262 navMethod = getContent("doclet.navMethod"); 263 navModuleDescription = getContent("doclet.navModuleDescription"); 264 navModules = getContent("doclet.navModules"); 265 navNested = getContent("doclet.navNested"); 266 navPackages = getContent("doclet.navPackages"); 267 navProperty = getContent("doclet.navProperty"); 268 navServices = getContent("doclet.navServices"); 269 nestedClassSummary = getContent("doclet.Nested_Class_Summary"); 270 newPage = new Comment(resources.getText("doclet.New_Page")); 271 noFramesLabel = getNonBreakContent("doclet.No_Frames"); 272 noScriptMessage = getContent("doclet.No_Script_Message"); 273 openedTo = getContent("doclet.OpenedTo"); 274 openModuleLabel = getContent("doclet.Open_Module"); 275 overridesLabel = getContent("doclet.Overrides"); 276 overviewLabel = getContent("doclet.Overview"); 277 packageHierarchies = getContent("doclet.Package_Hierarchies"); 278 packageLabel = getContent("doclet.Package"); 279 package_ = getContent("doclet.package"); 280 packagesLabel = getContent("doclet.Packages"); 281 properties = getContent("doclet.Properties"); 282 propertyLabel = getContent("doclet.Property"); 283 propertyDetailsLabel = getContent("doclet.Property_Detail"); 284 propertySummaryLabel = getContent("doclet.Property_Summary"); 285 seeLabel = getContent("doclet.See"); 286 serializedForm = getContent("doclet.Serialized_Form"); 287 servicesLabel = getContent("doclet.Services"); 288 specifiedByLabel = getContent("doclet.Specified_By"); 289 subclassesLabel = getContent("doclet.Subclasses"); 290 subinterfacesLabel = getContent("doclet.Subinterfaces"); 291 summaryLabel = getContent("doclet.Summary"); 292 treeLabel = getContent("doclet.Tree"); 293 typeLabel = getContent("doclet.Type"); 294 useLabel = getContent("doclet.navClassUse"); 295 valueLabel = getContent("doclet.Value"); 296 297 navLinkLabels = new EnumMap<>(VisibleMemberTable.Kind.class); 298 navLinkLabels.put(VisibleMemberTable.Kind.INNER_CLASSES, getContent("doclet.navNested")); 299 navLinkLabels.put(VisibleMemberTable.Kind.ENUM_CONSTANTS, getContent("doclet.navEnum")); 300 navLinkLabels.put(VisibleMemberTable.Kind.FIELDS, getContent("doclet.navField")); 301 navLinkLabels.put(VisibleMemberTable.Kind.CONSTRUCTORS, getContent("doclet.navConstructor")); 302 navLinkLabels.put(VisibleMemberTable.Kind.METHODS, getContent("doclet.navMethod")); 303 } 304 305 /** 306 * Gets a {@code Content} object, containing the string for 307 * a given key in the doclet's resources. 308 * 309 * @param key the key for the desired string 310 * @return a content tree for the string 311 */ 312 public Content getContent(String key) { 313 return new FixedStringContent(resources.getText(key)); 314 } 315 316 /** 317 * Gets a {@code Content} object, containing the string for 318 * a given key in the doclet's resources, formatted with 319 * given arguments. 320 * 321 * @param key the key for the desired string 322 * @param o0 string or content argument to be formatted into the result 323 * @return a content tree for the text 324 */ 325 public Content getContent(String key, Object o0) { 326 return getContent(key, o0, null, null); 327 } 328 329 /** 330 * Gets a {@code Content} object, containing the string for 331 * a given key in the doclet's resources, formatted with 332 * given arguments. 333 334 * @param key the key for the desired string 335 * @param o0 string or content argument to be formatted into the result 336 * @param o1 string or content argument to be formatted into the result 337 * @return a content tree for the text 338 */ 339 public Content getContent(String key, Object o0, Object o1) { 340 return getContent(key, o0, o1, null); 341 } 342 343 /** 344 * Gets a {@code Content} object, containing the string for 345 * a given key in the doclet's resources, formatted with 346 * given arguments. 347 * 348 * @param key the key for the desired string 349 * @param o0 string or content argument to be formatted into the result 350 * @param o1 string or content argument to be formatted into the result 351 * @param o2 string or content argument to be formatted into the result 352 * @return a content tree for the text 353 */ 354 public Content getContent(String key, Object o0, Object o1, Object o2) { 355 Content c = new ContentBuilder(); 356 Pattern p = Pattern.compile("\\{([012])\\}"); 357 String text = resources.getText(key); // TODO: cache 358 Matcher m = p.matcher(text); 359 int start = 0; 360 while (m.find(start)) { 361 c.add(text.substring(start, m.start())); 362 363 Object o = null; 364 switch (m.group(1).charAt(0)) { 365 case '0': o = o0; break; 366 case '1': o = o1; break; 367 case '2': o = o2; break; 368 } 369 370 if (o == null) { 371 c.add("{" + m.group(1) + "}"); 372 } else if (o instanceof String) { 373 c.add((String) o); 374 } else if (o instanceof Content) { 375 c.add((Content) o); 376 } 377 378 start = m.end(); 379 } 380 381 c.add(text.substring(start)); 382 return c; 383 } 384 385 /** 386 * Gets a {@code Content} object, containing the string for 387 * a given key in the doclet's resources, substituting 388 * <code> </code> for any space characters found in 389 * the named resource string. 390 * 391 * @param key the key for the desired string 392 * @return a content tree for the string 393 */ 394 private Content getNonBreakContent(String key) { 395 String text = resources.getText(key); // TODO: cache 396 Content c = new ContentBuilder(); 397 int start = 0; 398 int p; 399 while ((p = text.indexOf(" ", start)) != -1) { 400 c.add(text.substring(start, p)); 401 c.add(Entity.NO_BREAK_SPACE); 402 start = p + 1; 403 } 404 c.add(text.substring(start)); 405 return c; // TODO: should be made immutable 406 } 407 408 /** 409 * Returns a content for a visible member kind. 410 * @param kind the visible member table kind. 411 * @return the string content 412 */ 413 public Content getNavLinkLabelContent(VisibleMemberTable.Kind kind) { 414 return Objects.requireNonNull(navLinkLabels.get(kind)); 415 } 416 }