summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosCfgMojo.java
blob: 3e3e17a0010aed83f4ca5ae26cc78cdcf264874a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.maven;

import com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * Produces ONOS component configuration catalogue resources.
 */
@Mojo(name = "cfg", defaultPhase = LifecyclePhase.GENERATE_RESOURCES)
public class OnosCfgMojo extends AbstractMojo {

    private static final String COMPONENT = "org.apache.felix.scr.annotations.Component";
    private static final String PROPERTY = "org.apache.felix.scr.annotations.Property";
    private static final String SEP = "|";

    /**
     * The directory where the generated catalogue file will be put.
     */
    @Parameter(defaultValue = "${basedir}")
    protected File srcDirectory;

    /**
     * The directory where the generated catalogue file will be put.
     */
    @Parameter(defaultValue = "${project.build.outputDirectory}")
    protected File dstDirectory;

    @Override
    public void execute() throws MojoExecutionException {
        getLog().info("Generating ONOS component configuration catalogues...");
        try {
            JavaProjectBuilder builder = new JavaProjectBuilder();
            builder.addSourceTree(new File(srcDirectory, "src/main/java"));
            builder.getClasses().forEach(this::processClass);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    private void processClass(JavaClass javaClass) {
        boolean isComponent = javaClass.getAnnotations().stream()
                .map(ja -> ja.getType().getName().equals(COMPONENT))
                .findFirst().isPresent();
        if (isComponent) {
            List<String> lines = new ArrayList<>();
            javaClass.getFields().forEach(field -> processField(lines, javaClass, field));
            if (!lines.isEmpty()) {
                writeCatalog(javaClass, lines);
            }
        }
    }

    private void writeCatalog(JavaClass javaClass, List<String> lines) {
        File dir = new File(dstDirectory, javaClass.getPackageName().replace('.', '/'));
        dir.mkdirs();

        File cfgDef = new File(dir, javaClass.getName().replace('.', '/') + ".cfgdef");
        try (FileWriter fw = new FileWriter(cfgDef);
             PrintWriter pw = new PrintWriter(fw)) {
            pw.println("# This file is auto-generated by onos-maven-plugin");
            lines.forEach(pw::println);
        } catch (IOException e) {
            System.err.println("Unable to write catalog for " + javaClass.getName());
            e.printStackTrace();
        }
    }

    private void processField(List<String> lines, JavaClass javaClass, JavaField field) {
        field.getAnnotations().forEach(ja -> {
            if (ja.getType().getName().equals(PROPERTY)) {
                lines.add(expand(javaClass, ja.getNamedParameter("name").toString()) +
                                  SEP + type(field) +
                                  SEP + defaultValue(javaClass, field, ja) +
                                  SEP + description(ja));
            }
        });
    }

    // TODO: Stuff below is very much hack-ish and should be redone; it works for now though.

    private String description(JavaAnnotation annotation) {
        String description = (String) annotation.getNamedParameter("label");
        return description.replaceAll("\" \\+ \"", "")
                .replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
    }

    private String type(JavaField field) {
        String ft = field.getType().getName().toUpperCase();
        return ft.equals("INT") ? "INTEGER" : ft;
    }

    private String defaultValue(JavaClass javaClass, JavaField field,
                                JavaAnnotation annotation) {
        String ft = field.getType().getName().toLowerCase();
        String defValueName = ft.equals("boolean") ? "boolValue" :
                ft.equals("string") ? "value" : ft + "Value";
        Object dv = annotation.getNamedParameter(defValueName);
        return dv == null ? "" : expand(javaClass, dv.toString());
    }

    private String stripQuotes(String string) {
        return string.trim().replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
    }

    private String expand(JavaClass javaClass, String value) {
        JavaField field = javaClass.getFieldByName(value);
        return field == null ? stripQuotes(value) :
                stripQuotes(field.getCodeBlock().replaceFirst(".*=", "").replaceFirst(";$", ""));
    }

}