2 * Copyright (c) 2014 Brocade Communications 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
8 package org.opendaylight.mdsal.binding.generator.util;
10 import com.google.common.io.Files;
11 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 import java.io.BufferedWriter;
14 import java.io.IOException;
15 import java.nio.charset.StandardCharsets;
16 import javassist.CtClass;
17 import javassist.CtField;
18 import javassist.CtMethod;
19 import javassist.Modifier;
20 import javassist.NotFoundException;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
25 * The default implementation of the SourceCodeGenerator interface that generates readable source code
26 * for a runtime generated class. The appendField/appendMethod methods output source code to a temporary
27 * StringBuilder. When outputGeneratedSource is called, the entire class source code is generated and
28 * written to a file under a specified directory.
30 * @author Thomas Pantelis
32 * @deprecated Code generation is a concert separate from type mapping and is an implementation detail.
35 public class DefaultSourceCodeGenerator implements SourceCodeGenerator {
36 private static final Logger LOG = LoggerFactory.getLogger(DefaultSourceCodeGenerator.class);
38 private static final String GENERATED_SOURCE_DIR_PROP = "org.opendaylight.yangtools.sal.generatedCodecSourceDir";
40 private final StringBuilder builder = new StringBuilder();
41 private final String generatedSourceDir;
46 * @param generatedSourceDir the directory in which to put generated source files. If null, the directory
47 * is obtained from a system property (<i>org.opendaylight.yangtools.sal.generatedCodecSourceDir</i>) or
48 * defaults to "generated-codecs".
50 public DefaultSourceCodeGenerator(final String generatedSourceDir) {
51 if (generatedSourceDir != null) {
52 this.generatedSourceDir = generatedSourceDir;
54 this.generatedSourceDir = System.getProperty(GENERATED_SOURCE_DIR_PROP, "generated-codecs");
59 public void appendField(final CtField field, final String value) {
62 .append(Modifier.toString(field.getModifiers()))
63 .append(' ').append(field.getType().getName()).append(' ')
64 .append(field.getName());
66 builder.append(" = ").append(value);
69 builder.append(";\n");
70 } catch (NotFoundException e) {
71 LOG.error("Error building field source for {}", field.getName(), e);
76 public void appendMethod(final CtMethod method, final String code) {
79 .append(Modifier.toString(method.getModifiers()))
80 .append(' ').append(method.getReturnType().getName())
81 .append(' ').append(method.getName()).append("( ");
83 CtClass[] paramTypes = method.getParameterTypes();
84 if (paramTypes != null) {
85 for (int i = 0; i < paramTypes.length; i++) {
89 builder.append(paramTypes[i].getName()).append(" $")
94 builder.append(" )\n").append(code).append("\n\n");
95 } catch (NotFoundException e) {
96 LOG.error("Error building method source for {}", method.getName(), e);
101 @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
102 public void outputGeneratedSource(final CtClass ctClass) {
103 String name = ctClass.getName();
105 StringBuilder classBuilder = new StringBuilder();
106 classBuilder.append(Modifier.toString(ctClass.getModifiers()))
107 .append(" class ").append(ctClass.getSimpleName());
110 CtClass superClass = ctClass.getSuperclass();
111 if (superClass != null) {
112 classBuilder.append(" extends ").append(superClass.getName());
115 CtClass[] interfaces = ctClass.getInterfaces();
116 if (interfaces.length > 0) {
117 classBuilder.append(" implements ");
118 for (int i = 0; i < interfaces.length; i++) {
120 classBuilder.append(", ");
123 classBuilder.append(interfaces[i].getName());
127 classBuilder.append(" {\n").append(builder).append("\n}");
128 } catch (NotFoundException e) {
129 LOG.error("Error building class source for {}", name, e);
133 File dir = new File(generatedSourceDir);
135 LOG.warn("Failed to create directory {}, attempting to continue", generatedSourceDir);
138 try (BufferedWriter writer = Files.newWriter(new File(dir, name + ".java"), StandardCharsets.UTF_8)) {
139 writer.append(classBuilder);
141 } catch (IOException e) {
142 LOG.error("Error writing class source for {}", name, e);