Seal SchemaSourceRepresentation hierarchy
[yangtools.git] / plugin / yang-maven-plugin / src / main / java / org / opendaylight / yangtools / yang2sources / plugin / CodeGeneratorTaskFactory.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang2sources.plugin;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.MoreObjects.ToStringHelper;
13 import java.io.File;
14 import java.lang.reflect.Constructor;
15 import java.lang.reflect.InvocationTargetException;
16 import org.apache.maven.model.Resource;
17 import org.apache.maven.plugin.MojoFailureException;
18 import org.apache.maven.project.MavenProject;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.opendaylight.yangtools.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
21 import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
22 import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator.ImportResolutionMode;
23 import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Bridge to legacy {@link BasicCodeGenerator} generation.
29  *
30  * @author Robert Varga
31  */
32 final class CodeGeneratorTaskFactory extends GeneratorTaskFactory {
33     private static final Logger LOG = LoggerFactory.getLogger(CodeGeneratorTaskFactory.class);
34
35     private final @NonNull BasicCodeGenerator gen;
36     private final CodeGeneratorArg cfg;
37
38     private CodeGeneratorTaskFactory(final ImportResolutionMode importMode, final BasicCodeGenerator gen,
39             final CodeGeneratorArg cfg) {
40         super(importMode.toFileGeneratorMode());
41         this.gen = requireNonNull(gen);
42         this.cfg = requireNonNull(cfg);
43     }
44
45     static GeneratorTaskFactory create(final CodeGeneratorArg cfg) throws MojoFailureException {
46         cfg.check();
47
48         final String codegenClass = cfg.getCodeGeneratorClass();
49         final Class<?> clazz;
50         try {
51             clazz = Class.forName(codegenClass);
52         } catch (ClassNotFoundException e) {
53             throw new MojoFailureException("Failed to find code generator class " + codegenClass, e);
54         }
55         final Class<? extends BasicCodeGenerator> typedClass;
56         try {
57             typedClass = clazz.asSubclass(BasicCodeGenerator.class);
58         } catch (ClassCastException e) {
59             throw new MojoFailureException("Code generator " + clazz + " does not implement "
60                 + BasicCodeGenerator.class, e);
61         }
62         final Constructor<? extends BasicCodeGenerator> ctor;
63         try {
64             ctor = typedClass.getDeclaredConstructor();
65         } catch (NoSuchMethodException e) {
66             throw new MojoFailureException("Code generator " + clazz
67                 + " does not have an accessible no-argument constructor", e);
68         }
69         final @NonNull BasicCodeGenerator gen;
70         try {
71             gen = ctor.newInstance();
72         } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
73             throw new MojoFailureException("Failed to instantiate code generator " + clazz, e);
74         }
75         LOG.debug("Code generator instantiated from {}", codegenClass);
76
77         ImportResolutionMode importMode = gen.getImportResolutionMode();
78         if (importMode == null) {
79             importMode = ImportResolutionMode.REVISION_EXACT_OR_LATEST;
80         }
81         return new CodeGeneratorTaskFactory(importMode, gen, cfg);
82     }
83
84     @Override
85     CodeGeneratorTask createTask(final MavenProject project, final ContextHolder context) {
86         if (gen instanceof MavenProjectAware) {
87             ((MavenProjectAware)gen).setMavenProject(project);
88         }
89
90         LOG.debug("Project root dir is {}", project.getBasedir());
91         LOG.debug("{} Additional configuration picked up for : {}: {}", YangToSourcesProcessor.LOG_PREFIX,
92             generatorName(), cfg.getAdditionalConfiguration());
93
94         final File outputDir = cfg.getOutputBaseDir(project);
95         project.addCompileSourceRoot(outputDir.getAbsolutePath());
96
97         gen.setAdditionalConfig(cfg.getAdditionalConfiguration());
98         File resourceBaseDir = cfg.getResourceBaseDir(project);
99
100         final Resource res = new Resource();
101         res.setDirectory(resourceBaseDir.getPath());
102         project.addResource(res);
103
104         gen.setResourceBaseDir(resourceBaseDir);
105         LOG.debug("Folder: {} marked as resources for generator: {}", resourceBaseDir, generatorName());
106         return new CodeGeneratorTask(this, context, outputDir);
107     }
108
109     @Override
110     BasicCodeGenerator generator() {
111         return gen;
112     }
113
114     @Override
115     ToStringHelper addToStringProperties(final ToStringHelper helper) {
116         return super.addToStringProperties(helper).add("configuration", cfg);
117     }
118 }