1/*
2 * Copyright (c) 2015, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24package sampleapi.generator;
25
26import java.util.ArrayList;
27import java.util.Set;
28import javax.lang.model.element.Modifier;
29
30import com.sun.tools.javac.util.Context;
31import com.sun.tools.javac.tree.JCTree;
32import com.sun.tools.javac.tree.JCTree.*;
33import com.sun.tools.javac.tree.DocCommentTable;
34import com.sun.tools.javac.parser.ScannerFactory;
35import com.sun.tools.javac.parser.Scanner;
36import com.sun.tools.javac.parser.Tokens.Token;
37import com.sun.tools.javac.parser.Tokens.Comment;
38import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
39import com.sun.source.tree.Tree.Kind;
40
41import sampleapi.util.*;
42
43class Documentifier {
44
45    static Documentifier instance;
46
47    final DocCommentGenerator docGen;
48    final ScannerFactory scanners;
49
50    private Documentifier(Context context) {
51        docGen = new DocCommentGenerator();
52        scanners = ScannerFactory.instance(context);
53    }
54
55    public static Documentifier instance(Context context) {
56        if (instance == null)
57            instance = new Documentifier(context);
58        return instance;
59    }
60
61    private DocCommentTable curDocComments;
62
63    public void documentify(JCCompilationUnit topLevel, boolean isFxStyle) {
64        JCClassDecl base = (JCClassDecl)topLevel.getTypeDecls().get(0);
65        curDocComments = new PoorDocCommentTable();
66        documentifyBase(base, true, isFxStyle);
67        topLevel.docComments = curDocComments;
68    }
69
70    private void documentifyBase(JCClassDecl base, boolean isTopLevel, boolean isFxStyle) {
71        // add doc comment to class itself
72        Comment comm = comment(docGen.getBaseComment(base, isTopLevel));
73        curDocComments.putComment(base, comm);
74
75        // add doc comments to members
76        for (JCTree member : base.getMembers()) {
77            switch (member.getTag()) {
78                case VARDEF:
79                    documentifyField(base, (JCVariableDecl)member, isFxStyle);
80                    break;
81                case METHODDEF:
82                    documentifyMethod(base, (JCMethodDecl)member, isFxStyle);
83                    break;
84                case CLASSDEF:
85                    documentifyBase((JCClassDecl)member, false, isFxStyle);
86                    break;
87            }
88        }
89    }
90
91    private void documentifyField(JCClassDecl base, JCVariableDecl field, boolean isFxStyle) {
92        Kind baseKind = base.getKind();
93        Set<Modifier> fieldMods = field.getModifiers().getFlags();
94        String doc = (baseKind == Kind.ENUM
95                      && fieldMods.contains(Modifier.PUBLIC)
96                      && fieldMods.contains(Modifier.STATIC)
97                      && fieldMods.contains(Modifier.FINAL)) ?
98                     docGen.getConstComment() :
99                     docGen.getFieldComment(base, field, isFxStyle);
100        Comment comm = comment(doc);
101        curDocComments.putComment(field, comm);
102    }
103
104    private void documentifyMethod(JCClassDecl base, JCMethodDecl method, boolean isFxStyle) {
105        Comment comm = comment(docGen.getMethodComment(base, method, isFxStyle));
106        curDocComments.putComment(method, comm);
107    }
108
109    private Comment comment(String docString) {
110        StringBuilder docComment = new StringBuilder()
111                                   .append("/**")
112                                   .append(docString)
113                                   .append("*/");
114        Scanner scanner = scanners.newScanner(docComment, true);
115        scanner.nextToken();
116        Token token = scanner.token();
117        return token.comment(CommentStyle.JAVADOC);
118    }
119
120    // provide package comment data ONLY
121    public DocCommentGenerator getDocGenerator() {
122        return docGen;
123    }
124}
125