1 /* 2 * Copyright (c) 1998, 2017, 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.regex.Matcher; 29 import java.util.regex.Pattern; 30 31 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; 32 import jdk.javadoc.internal.doclets.formats.html.markup.FixedStringContent; 33 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml; 34 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 35 import jdk.javadoc.internal.doclets.toolkit.Content; 36 import jdk.javadoc.internal.doclets.toolkit.Resources; 37 import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; 38 39 /** 40 * Constants and factory methods for common fragments of content 41 * used by HtmlDoclet. The string content of these fragments is 42 * generally obtained from the {@link Resources resources} found 43 * in the doclet's configuration. 44 * 45 * @implNote 46 * Many constants are made available in this class, so that they are 47 * only created once per doclet-instance, instead of once per generated page. 48 */ 49 public class Contents { 50 public static final Content SPACE = RawHtml.nbsp; 51 public static final Content ZERO_WIDTH_SPACE = RawHtml.zws; 52 53 public final Content allClassesLabel; 54 public final Content allImplementedInterfacesLabel; 55 public final Content allModulesLabel; 56 public final Content allPackagesLabel; 57 public final Content allSuperinterfacesLabel; 58 public final Content also; 59 public final Content annotateTypeOptionalMemberSummaryLabel; 60 public final Content annotateTypeRequiredMemberSummaryLabel; 61 public final Content annotationType; 62 public final Content annotationTypeDetailsLabel; 63 public final Content annotationTypeMemberDetail; 64 public final Content annotationTypes; 65 public final Content classLabel; 66 public final Content classes; 67 public final Content constantsSummaryTitle; 68 public final Content constructorDetailsLabel; 69 public final Content constructorSummaryLabel; 70 public final Content constructors; 71 public final Content contentsHeading; 72 public final Content defaultPackageLabel; 73 public final Content default_; 74 public final Content deprecatedAPI; 75 public final Content deprecatedLabel; 76 public final Content deprecatedPhrase; 77 public final Content deprecatedForRemovalPhrase; 78 public final Content descfrmClassLabel; 79 public final Content descfrmInterfaceLabel; 80 public final Content descriptionLabel; 81 public final Content detailLabel; 82 public final Content enclosingClassLabel; 83 public final Content enclosingInterfaceLabel; 84 public final Content enumConstantDetailLabel; 85 public final Content enumConstantSummary; 86 public final Content enum_; 87 public final Content enums; 88 public final Content errors; 89 public final Content exceptions; 90 public final Content fieldDetailsLabel; 91 public final Content fieldSummaryLabel; 92 public final Content fields; 93 public final Content framesLabel; 94 public final Content functionalInterface; 95 public final Content functionalInterfaceMessage; 96 public final Content helpLabel; 97 public final Content hierarchyForAllPackages; 98 public final Content implementation; 99 public final Content implementingClassesLabel; 100 public final Content inClass; 101 public final Content inInterface; 102 public final Content indexLabel; 103 public final Content interfaces; 104 public final Content interfacesItalic; 105 public final Content methodDetailLabel; 106 public final Content methodSummary; 107 public final Content methods; 108 public final Content moduleLabel; 109 public final Content module_; 110 public final Content moduleSubNavLabel; 111 public final Content modulesLabel; 112 public final Content navAnnotationTypeMember; 113 public final Content navAnnotationTypeOptionalMember; 114 public final Content navAnnotationTypeRequiredMember; 115 public final Content navConstructor; 116 public final Content navEnum; 117 public final Content navField; 118 public final Content navMethod; 119 public final Content navModuleDescription; 120 public final Content navModules; 121 public final Content navNested; 122 public final Content navPackages; 123 public final Content navProperty; 124 public final Content navServices; 125 public final Content nestedClassSummary; 126 public final Content nextClassLabel; 127 public final Content nextLabel; 128 public final Content nextLetter; 129 public final Content nextModuleLabel; 130 public final Content nextPackageLabel; 131 public final Content noFramesLabel; 132 public final Content noScriptMessage; 133 public final Content openModuleLabel; 134 public final Content overridesLabel; 135 public final Content overviewLabel; 136 public final Content packageHierarchies; 137 public final Content packageLabel; 138 public final Content package_; 139 public final Content packagesLabel; 140 public final Content prevClassLabel; 141 public final Content prevLabel; 142 public final Content prevLetter; 143 public final Content prevModuleLabel; 144 public final Content prevPackageLabel; 145 public final Content properties; 146 public final Content propertyDetailsLabel; 147 public final Content propertySummary; 148 public final Content seeLabel; 149 public final Content serializedForm; 150 public final Content specifiedByLabel; 151 public final Content subclassesLabel; 152 public final Content subinterfacesLabel; 153 public final Content summaryLabel; 154 public final Content treeLabel; 155 public final Content useLabel; 156 157 private final Resources resources; 158 159 /** 160 * Creates a {@code Contents} object. 161 * 162 * @param configuration the configuration in which to find the 163 * resources used to look up resource keys, and other details. 164 */ 165 Contents(HtmlConfiguration configuration) { 166 this.resources = configuration.getResources(); 167 168 allClassesLabel = getNonBreakContent("doclet.All_Classes"); 169 allImplementedInterfacesLabel = getContent("doclet.All_Implemented_Interfaces"); 170 allModulesLabel = getNonBreakContent("doclet.All_Modules"); 171 allPackagesLabel = getNonBreakContent("doclet.All_Packages"); 172 allSuperinterfacesLabel = getContent("doclet.All_Superinterfaces"); 173 also = getContent("doclet.also"); 174 annotateTypeOptionalMemberSummaryLabel = getContent("doclet.Annotation_Type_Optional_Member_Summary"); 175 annotateTypeRequiredMemberSummaryLabel = getContent("doclet.Annotation_Type_Required_Member_Summary"); 176 annotationType = getContent("doclet.AnnotationType"); 177 annotationTypeDetailsLabel = getContent("doclet.Annotation_Type_Member_Detail"); 178 annotationTypeMemberDetail = getContent("doclet.Annotation_Type_Member_Detail"); 179 annotationTypes = getContent("doclet.AnnotationTypes"); 180 classLabel = getContent("doclet.Class"); 181 classes = getContent("doclet.Classes"); 182 constantsSummaryTitle = getContent("doclet.Constants_Summary"); 183 constructorDetailsLabel = getContent("doclet.Constructor_Detail"); 184 constructorSummaryLabel = getContent("doclet.Constructor_Summary"); 185 constructors = getContent("doclet.Constructors"); 186 contentsHeading = getContent("doclet.Contents"); 187 defaultPackageLabel = new StringContent(DocletConstants.DEFAULT_PACKAGE_NAME); 188 default_ = getContent("doclet.Default"); 189 deprecatedAPI = getContent("doclet.Deprecated_API"); 190 deprecatedLabel = getContent("doclet.navDeprecated"); 191 deprecatedPhrase = getContent("doclet.Deprecated"); 192 deprecatedForRemovalPhrase = getContent("doclet.DeprecatedForRemoval"); 193 descfrmClassLabel = getContent("doclet.Description_From_Class"); 194 descfrmInterfaceLabel = getContent("doclet.Description_From_Interface"); 195 descriptionLabel = getContent("doclet.Description"); 196 detailLabel = getContent("doclet.Detail"); 197 enclosingClassLabel = getContent("doclet.Enclosing_Class"); 198 enclosingInterfaceLabel = getContent("doclet.Enclosing_Interface"); 199 enumConstantDetailLabel = getContent("doclet.Enum_Constant_Detail"); 200 enumConstantSummary = getContent("doclet.Enum_Constant_Summary"); 201 enum_ = getContent("doclet.Enum"); 202 enums = getContent("doclet.Enums"); 203 errors = getContent("doclet.Errors"); 204 exceptions = getContent("doclet.Exceptions"); 205 fieldDetailsLabel = getContent("doclet.Field_Detail"); 206 fieldSummaryLabel = getContent("doclet.Field_Summary"); 207 fields = getContent("doclet.Fields"); 208 framesLabel = getContent("doclet.Frames"); 209 functionalInterface = getContent("doclet.Functional_Interface"); 210 functionalInterfaceMessage = getContent("doclet.Functional_Interface_Message"); 211 helpLabel = getContent("doclet.Help"); 212 hierarchyForAllPackages = getContent("doclet.Hierarchy_For_All_Packages"); 213 implementation = getContent("doclet.Implementation"); 214 implementingClassesLabel = getContent("doclet.Implementing_Classes"); 215 inClass = getContent("doclet.in_class"); 216 inInterface = getContent("doclet.in_interface"); 217 indexLabel = getContent("doclet.Index"); 218 interfaces = getContent("doclet.Interfaces"); 219 interfacesItalic = getContent("doclet.Interfaces_Italic"); 220 methodDetailLabel = getContent("doclet.Method_Detail"); 221 methodSummary = getContent("doclet.Method_Summary"); 222 methods = getContent("doclet.Methods"); 223 moduleLabel = getContent("doclet.Module"); 224 module_ = getContent("doclet.module"); 225 moduleSubNavLabel = getContent("doclet.Module_Sub_Nav"); 226 modulesLabel = getContent("doclet.Modules"); 227 navAnnotationTypeMember = getContent("doclet.navAnnotationTypeMember"); 228 navAnnotationTypeOptionalMember = getContent("doclet.navAnnotationTypeOptionalMember"); 229 navAnnotationTypeRequiredMember = getContent("doclet.navAnnotationTypeRequiredMember"); 230 navConstructor = getContent("doclet.navConstructor"); 231 navEnum = getContent("doclet.navEnum"); 232 navField = getContent("doclet.navField"); 233 navMethod = getContent("doclet.navMethod"); 234 navModuleDescription = getContent("doclet.navModuleDescription"); 235 navModules = getContent("doclet.navModules"); 236 navNested = getContent("doclet.navNested"); 237 navPackages = getContent("doclet.navPackages"); 238 navProperty = getContent("doclet.navProperty"); 239 navServices = getContent("doclet.navServices"); 240 nestedClassSummary = getContent("doclet.Nested_Class_Summary"); 241 nextClassLabel = getNonBreakContent("doclet.Next_Class"); 242 nextLabel = getNonBreakContent("doclet.Next"); 243 nextLetter = getContent("doclet.Next_Letter"); 244 nextModuleLabel = getNonBreakContent("doclet.Next_Module"); 245 nextPackageLabel = getNonBreakContent("doclet.Next_Package"); 246 noFramesLabel = getNonBreakContent("doclet.No_Frames"); 247 noScriptMessage = getContent("doclet.No_Script_Message"); 248 openModuleLabel = getContent("doclet.Open_Module"); 249 overridesLabel = getContent("doclet.Overrides"); 250 overviewLabel = getContent("doclet.Overview"); 251 packageHierarchies = getContent("doclet.Package_Hierarchies"); 252 packageLabel = getContent("doclet.Package"); 253 package_ = getContent("doclet.package"); 254 packagesLabel = getContent("doclet.Packages"); 255 prevClassLabel = getNonBreakContent("doclet.Prev_Class"); 256 prevLabel = getContent("doclet.Prev"); 257 prevLetter = getContent("doclet.Prev_Letter"); 258 prevModuleLabel = getNonBreakContent("doclet.Prev_Module"); 259 prevPackageLabel = getNonBreakContent("doclet.Prev_Package"); 260 properties = getContent("doclet.Properties"); 261 propertyDetailsLabel = getContent("doclet.Property_Detail"); 262 propertySummary = getContent("doclet.Property_Summary"); 263 seeLabel = getContent("doclet.See"); 264 serializedForm = getContent("doclet.Serialized_Form"); 265 specifiedByLabel = getContent("doclet.Specified_By"); 266 subclassesLabel = getContent("doclet.Subclasses"); 267 subinterfacesLabel = getContent("doclet.Subinterfaces"); 268 summaryLabel = getContent("doclet.Summary"); 269 treeLabel = getContent("doclet.Tree"); 270 useLabel = getContent("doclet.navClassUse"); 271 } 272 273 /** 274 * Gets a {@code Content} object, containing the string for 275 * a given key in the doclet's resources. 276 * 277 * @param key the key for the desired string 278 * @return a content tree for the string 279 */ 280 public Content getContent(String key) { 281 return new FixedStringContent(resources.getText(key)); 282 } 283 284 /** 285 * Gets a {@code Content} object, containing the string for 286 * a given key in the doclet's resources, formatted with 287 * given arguments. 288 * 289 * @param key the key to look for in the configuration fil 290 * @param key the key for the desired string 291 * @param o0 string or content argument to be formatted into the result 292 * @return a content tree for the text 293 */ 294 public Content getContent(String key, Object o0) { 295 return getContent(key, o0, null, null); 296 } 297 298 /** 299 * Gets a {@code Content} object, containing the string for 300 * a given key in the doclet's resources, formatted with 301 * given arguments. 302 303 * @param key the key for the desired string 304 * @param o0 string or content argument to be formatted into the result 305 * @param o1 string or content argument to be formatted into the result 306 * @return a content tree for the text 307 */ 308 public Content getContent(String key, Object o0, Object o1) { 309 return getContent(key, o0, o1, null); 310 } 311 312 /** 313 * Gets a {@code Content} object, containing the string for 314 * a given key in the doclet's resources, formatted with 315 * given arguments. 316 * 317 * @param key the key for the desired string 318 * @param o0 string or content argument to be formatted into the result 319 * @param o1 string or content argument to be formatted into the result 320 * @param o2 string or content argument to be formatted into the result 321 * @return a content tree for the text 322 */ 323 public Content getContent(String key, Object o0, Object o1, Object o2) { 324 Content c = new ContentBuilder(); 325 Pattern p = Pattern.compile("\\{([012])\\}"); 326 String text = resources.getText(key); // TODO: cache 327 Matcher m = p.matcher(text); 328 int start = 0; 329 while (m.find(start)) { 330 c.addContent(text.substring(start, m.start())); 331 332 Object o = null; 333 switch (m.group(1).charAt(0)) { 334 case '0': o = o0; break; 335 case '1': o = o1; break; 336 case '2': o = o2; break; 337 } 338 339 if (o == null) { 340 c.addContent("{" + m.group(1) + "}"); 341 } else if (o instanceof String) { 342 c.addContent((String) o); 343 } else if (o instanceof Content) { 344 c.addContent((Content) o); 345 } 346 347 start = m.end(); 348 } 349 350 c.addContent(text.substring(start)); 351 return c; 352 } 353 354 /** 355 * Gets a {@code Content} object, containing the string for 356 * a given key in the doclet's resources, substituting 357 * <code> </code> for any space characters found in 358 * the named resource string. 359 * 360 * @param key the key for the desired string 361 * @return a content tree for the string 362 */ 363 private Content getNonBreakContent(String key) { 364 String text = resources.getText(key); // TODO: cache 365 Content c = new ContentBuilder(); 366 int start = 0; 367 int p; 368 while ((p = text.indexOf(" ", start)) != -1) { 369 c.addContent(text.substring(start, p)); 370 c.addContent(RawHtml.nbsp); 371 start = p + 1; 372 } 373 c.addContent(text.substring(start)); 374 return c; // TODO: should be made immutable 375 } 376 }