blob: b2742d7d38827b469cc1f764e928fb9482a1183c [file] [log] [blame]
Thomas Vachuska8c8b0372015-03-10 11:11:24 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.maven;
17
18import com.thoughtworks.qdox.JavaProjectBuilder;
19import com.thoughtworks.qdox.model.JavaAnnotation;
20import com.thoughtworks.qdox.model.JavaClass;
21import com.thoughtworks.qdox.model.JavaField;
22import org.apache.maven.plugin.AbstractMojo;
23import org.apache.maven.plugin.MojoExecutionException;
24import org.apache.maven.plugins.annotations.LifecyclePhase;
25import org.apache.maven.plugins.annotations.Mojo;
26import org.apache.maven.plugins.annotations.Parameter;
27
28import java.io.File;
29import java.io.FileWriter;
30import java.io.IOException;
31import java.io.PrintWriter;
32import java.util.ArrayList;
33import java.util.List;
34
35/**
36 * Produces ONOS component configuration catalogue resources.
37 */
38@Mojo(name = "cfg", defaultPhase = LifecyclePhase.GENERATE_RESOURCES)
39public class OnosCfgMojo extends AbstractMojo {
40
41 private static final String COMPONENT = "org.apache.felix.scr.annotations.Component";
42 private static final String PROPERTY = "org.apache.felix.scr.annotations.Property";
43 private static final String SEP = "|";
44
45 /**
46 * The directory where the generated catalogue file will be put.
47 */
48 @Parameter( defaultValue = "${basedir}" )
49 protected File srcDirectory;
50
51 /**
52 * The directory where the generated catalogue file will be put.
53 */
54 @Parameter( defaultValue = "${project.build.outputDirectory}" )
55 protected File dstDirectory;
56
57 @Override
58 public void execute() throws MojoExecutionException {
59 getLog().info("Generating ONOS component configuration catalogues...");
60 try {
61 JavaProjectBuilder builder = new JavaProjectBuilder();
62 builder.addSourceTree(new File(srcDirectory, "src/main/java"));
63 builder.getClasses().forEach(this::processClass);
64 } catch (Exception e) {
65 e.printStackTrace();
66 throw e;
67 }
68 }
69
70 private void processClass(JavaClass javaClass) {
71 boolean isComponent = javaClass.getAnnotations().stream()
72 .map(ja -> ja.getType().getName().equals(COMPONENT))
73 .findFirst().isPresent();
74 if (isComponent) {
75 List<String> lines = new ArrayList<>();
76 javaClass.getFields().forEach(field -> processField(lines, javaClass, field));
77 if (!lines.isEmpty()) {
78 writeCatalog(javaClass, lines);
79 }
80 }
81 }
82
83 private void writeCatalog(JavaClass javaClass, List<String> lines) {
84 File dir = new File(dstDirectory, javaClass.getPackageName().replace('.', '/'));
85 dir.mkdirs();
86
87 File cfgDef = new File(dir, javaClass.getName().replace('.', '/') + ".cfgdef");
88 try (FileWriter fw = new FileWriter(cfgDef);
89 PrintWriter pw = new PrintWriter(fw)) {
90 pw.println("# This file is auto-generated by onos-maven-plugin");
91 lines.forEach(pw::println);
92 } catch (IOException e) {
93 System.err.println("Unable to write catalog for " + javaClass.getName());
94 e.printStackTrace();
95 }
96 }
97
98 private void processField(List<String> lines, JavaClass javaClass, JavaField field) {
99 field.getAnnotations().forEach(ja -> {
100 if (ja.getType().getName().equals(PROPERTY)) {
101 lines.add(expand(javaClass, ja.getNamedParameter("name").toString()) +
102 SEP + type(field) +
103 SEP + defaultValue(javaClass, field, ja) +
104 SEP + description(ja));
105 }
106 });
107 }
108
109 // TODO: Stuff below is very much hack-ish and should be redone; it works for now though.
110
111 private String description(JavaAnnotation annotation) {
112 String description = (String) annotation.getNamedParameter("label");
113 return description.replaceAll("\" \\+ \"", "")
114 .replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
115 }
116
117 private String type(JavaField field) {
118 String ft = field.getType().getName().toUpperCase();
119 return ft.equals("INT") ? "INTEGER" : ft;
120 }
121
122 private String defaultValue(JavaClass javaClass, JavaField field,
123 JavaAnnotation annotation) {
124 String ft = field.getType().getName().toLowerCase();
125 String defValueName = ft.equals("boolean") ? "boolValue" :
126 ft.equals("string") ? "value" : ft + "Value";
127 Object dv = annotation.getNamedParameter(defValueName);
128 return dv == null ? "" : expand(javaClass, dv.toString());
129 }
130
131 private String stripQuotes(String string) {
132 return string.trim().replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
133 }
134
135 private String expand(JavaClass javaClass, String value) {
136 JavaField field = javaClass.getFieldByName(value);
137 return field == null ? stripQuotes(value) :
138 stripQuotes(field.getCodeBlock().replaceFirst(".*=", "").replaceFirst(";$", ""));
139 }
140
141}