2 * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.mdsal.binding.javav2.java.api.generator.renderers;
11 import static org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer.normalizeFullPackageName;
12 import static org.opendaylight.mdsal.binding.javav2.util.BindingMapping.MODEL_BINDING_PROVIDER_CLASS_NAME;
13 import static org.opendaylight.mdsal.binding.javav2.util.BindingMapping.getRootPackageName;
15 import com.google.common.base.Optional;
16 import com.google.common.base.Preconditions;
17 import com.google.common.collect.ImmutableSet;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.util.Collections;
21 import java.util.Date;
22 import java.util.HashMap;
23 import java.util.HashSet;
26 import java.util.TreeMap;
27 import java.util.function.Function;
28 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
29 import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.modelProviderTemplate;
30 import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.yangModuleInfoTemplate;
31 import org.opendaylight.mdsal.binding.javav2.model.api.ParameterizedType;
32 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
33 import org.opendaylight.mdsal.binding.javav2.model.api.WildcardType;
34 import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModelBindingProvider;
35 import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModuleInfo;
36 import org.opendaylight.yangtools.concepts.SemVer;
37 import org.opendaylight.yangtools.yang.common.Revision;
38 import org.opendaylight.yangtools.yang.model.api.Module;
39 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
40 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
42 public class YangModuleInfoTemplateRenderer {
44 private final Module module;
45 private final SchemaContext ctx;
46 private final Map<String, String> importMap = new HashMap<>();
47 private final String packageName;
48 private final String modelBindingProviderName;
49 private final Function<Module, java.util.Optional<String>> moduleFilePathResolver;
51 public YangModuleInfoTemplateRenderer(final Module module, final SchemaContext ctx, final Function<Module,
52 java.util.Optional<String>> moduleFilePathResolver) {
54 Preconditions.checkArgument(module != null, "Module must not be null.");
57 this.packageName = normalizeFullPackageName(getRootPackageName(module));
58 this.moduleFilePathResolver = moduleFilePathResolver;
60 final StringBuilder sb = new StringBuilder();
61 sb.append(packageName)
63 .append(MODEL_BINDING_PROVIDER_CLASS_NAME);
64 this.modelBindingProviderName = sb.toString();
67 protected String body() {
69 * list of all imported names for template
71 final Map<String, String> importedNames = new HashMap<>();
73 importedNames.put("string", importedName(String.class));
74 importedNames.put("stringBuilder", importedName(StringBuilder.class));
75 importedNames.put("set", importedName(Set.class));
76 importedNames.put("hashSet", importedName(HashSet.class));
77 importedNames.put("collections", importedName(Collections.class));
78 importedNames.put("immutableSet", importedName(ImmutableSet.class));
79 importedNames.put("inputStream", importedName(InputStream.class));
80 importedNames.put("iOException", importedName(IOException.class));
81 importedNames.put("yangModuleInfo", importedName(YangModuleInfo.class));
82 importedNames.put("optional", importedName(Optional.class));
83 importedNames.put("semVer", importedName(SemVer.class));
84 importedNames.put("schemaSourceRepresentation", importedName(SchemaSourceRepresentation.class));
86 return yangModuleInfoTemplate.render(module, ctx, importedNames, moduleFilePathResolver).body();
91 * @return generated final template
93 public String generateTemplate() {
94 final StringBuilder sb = new StringBuilder();
95 /* body must be filled before imports method call */
96 final String templateBody = body();
101 .append(templateBody);
102 return sb.toString();
105 public String generateModelProvider() {
106 return modelProviderTemplate.render(packageName, YangModelBindingProvider.class.getName(), YangModuleInfo.class
111 * Walks through map of imports
112 * @return string of imports for template
114 private String imports() {
115 final StringBuilder sb = new StringBuilder();
116 for (Map.Entry<String, String> entry : importMap.entrySet()) {
117 if (!getRootPackageName(module).equals(entry.getValue())) {
119 .append(entry.getValue())
121 .append(entry.getKey())
125 return sb.toString();
128 private String importedName(final Class<?> cls) {
129 final Type inType = Types.typeForClass(cls);
130 putTypeIntoImports(inType);
131 return getExplicitType(inType);
134 private void putTypeIntoImports(final Type type) {
135 final String typeName = type.getName();
136 final String typePackageName = type.getPackageName();
137 if (typePackageName.startsWith("java.lang") || typePackageName.isEmpty()) {
140 if (!importMap.containsKey(typeName)) {
141 importMap.put(typeName, typePackageName);
143 if (type instanceof ParameterizedType) {
144 final Type[] params = ((ParameterizedType) type).getActualTypeArguments();
145 if (params != null) {
146 for (Type param : params) {
147 putTypeIntoImports(param);
153 private String getExplicitType(final Type type) {
154 final String typePackageName = type.getPackageName();
155 final String typeName = type.getName();
156 final String importedPackageName = importMap.get(typeName);
157 final StringBuilder sb;
158 if (typePackageName.equals(importedPackageName)) {
159 sb = new StringBuilder(type.getName());
160 if (sb.toString().equals("Void")) {
163 addActualTypeParameters(sb, type);
165 if (type.equals(Types.voidType())) {
168 sb = new StringBuilder();
169 if (!typePackageName.isEmpty()) {
170 sb.append(typePackageName)
172 .append(type.getName());
174 sb.append(type.getName());
176 addActualTypeParameters(sb, type);
178 return sb.toString();
181 private StringBuilder addActualTypeParameters(final StringBuilder sb, final Type type) {
182 if (type instanceof ParameterizedType) {
183 final Type[] pTypes = ((ParameterizedType) type).getActualTypeArguments();
185 sb.append(getParameters(pTypes));
191 private String getParameters(final Type[] pTypes) {
192 if (pTypes == null || pTypes.length == 0) {
195 final StringBuilder sb = new StringBuilder();
197 for (Type pType : pTypes) {
198 final Type type = pTypes[i];
199 String separator = ",";
200 if (i == (pTypes.length - 1)) {
203 String wildcardParam = "";
204 if (type.equals(Types.voidType())) {
205 sb.append("java.lang.Void" + separator);
207 if (type instanceof WildcardType) {
208 wildcardParam = "? extends ";
210 sb.append(wildcardParam + getExplicitType(type) + separator);
214 return sb.toString();
217 public static Module getSortedQName(final Set<Module> modules, final String name) {
218 final TreeMap<java.util.Optional<Revision>, Module> sorted = new TreeMap<>(Revision::compare);
219 for (Module module : modules) {
220 if (name.equals(module.getName())) {
221 sorted.put(module.getRevision(), module);
224 return sorted.lastEntry().getValue();
227 public String getModelBindingProviderName() {
228 return modelBindingProviderName;