1/* 2 * Copyright (c) 2012, 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 26package jdk.javadoc.internal.api; 27 28import java.util.ArrayList; 29import java.util.Collections; 30import java.util.List; 31import java.util.Locale; 32import java.util.Objects; 33import java.util.concurrent.atomic.AtomicBoolean; 34 35import javax.tools.DocumentationTool.DocumentationTask; 36import javax.tools.JavaFileObject; 37 38import com.sun.tools.javac.main.Option; 39import com.sun.tools.javac.util.ClientCodeException; 40import com.sun.tools.javac.util.Context; 41import com.sun.tools.javac.util.Options; 42import jdk.javadoc.internal.tool.Start; 43 44/** 45 * Provides access to functionality specific to the JDK documentation tool, 46 * javadoc. 47 * 48 * <p><b>This is NOT part of any supported API. 49 * If you write code that depends on this, you do so at your own 50 * risk. This code and its internal interfaces are subject to change 51 * or deletion without notice.</b></p> 52 */ 53public class JavadocTaskImpl implements DocumentationTask { 54 private final AtomicBoolean used = new AtomicBoolean(); 55 56 private final Context context; 57 private Class<?> docletClass; 58 private Iterable<String> options; 59 private Iterable<? extends JavaFileObject> fileObjects; 60 private Locale locale; 61 private List<String> addModules = new ArrayList<>(); 62 63 public JavadocTaskImpl(Context context, Class<?> docletClass, 64 Iterable<String> options, Iterable<? extends JavaFileObject> fileObjects) { 65 this.context = context; 66 this.docletClass = docletClass; 67 68 this.options = (options == null) ? Collections.emptySet() 69 : nullCheck(options); 70 this.fileObjects = (fileObjects == null) ? Collections.emptySet() 71 : nullCheck(fileObjects); 72 setLocale(Locale.getDefault()); 73 } 74 75 public void setLocale(Locale locale) { 76 if (used.get()) 77 throw new IllegalStateException(); 78 this.locale = locale; 79 } 80 81 @Override 82 public void addModules(Iterable<String> moduleNames) { 83 nullCheck(moduleNames); 84 if (used.get()) 85 throw new IllegalStateException(); 86 for (String name : moduleNames) { 87 addModules.add(name); 88 } 89 } 90 91 public Boolean call() { 92 if (!used.getAndSet(true)) { 93 initContext(); 94 Start jdoc = new Start(context); 95 try { 96 return jdoc.begin(docletClass, options, fileObjects); 97 } catch (ClientCodeException e) { 98 throw new RuntimeException(e.getCause()); 99 } 100 } else { 101 throw new IllegalStateException("multiple calls to method 'call'"); 102 } 103 } 104 105 private void initContext() { 106 //initialize compiler's default locale 107 context.put(Locale.class, locale); 108 if (!addModules.isEmpty()) { 109 String names = String.join(",", addModules); 110 Options opts = Options.instance(context); 111 String prev = opts.get(Option.ADD_MODULES); 112 opts.put(Option.ADD_MODULES, (prev == null) ? names : prev + "," + names); 113 } 114 } 115 116 private static <T> Iterable<T> nullCheck(Iterable<T> items) { 117 for (T item: items) { 118 if (item == null) 119 throw new NullPointerException(); 120 } 121 return items; 122 } 123} 124