import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.apache.commons.io.FileUtils;
-import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator;
import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
-import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
+import org.opendaylight.mdsal.binding.yang.types.TypeProviderImpl;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.slf4j.impl.StaticLoggerBinder;
/**
* This class interfaces with yang-maven-plugin. Gets parsed yang modules in
* {@link SchemaContext}, and parameters form the plugin configuration, and
* writes service interfaces and/or modules.
*/
-public class JMXGenerator implements CodeGenerator {
+public class JMXGenerator implements BasicCodeGenerator, MavenProjectAware {
+ private static final class NamespaceMapping {
+ private final String namespace, packageName;
+ public NamespaceMapping(final String namespace, final String packagename) {
+ this.namespace = namespace;
+ this.packageName = packagename;
+ }
+ }
+
+ @VisibleForTesting
static final String NAMESPACE_TO_PACKAGE_DIVIDER = "==";
+ @VisibleForTesting
static final String NAMESPACE_TO_PACKAGE_PREFIX = "namespaceToPackage";
+ @VisibleForTesting
static final String MODULE_FACTORY_FILE_BOOLEAN = "moduleFactoryFile";
- private PackageTranslator packageTranslator;
+ private static final Logger LOG = LoggerFactory.getLogger(JMXGenerator.class);
+ private static final Pattern NAMESPACE_MAPPING_PATTERN = Pattern.compile("(.+)" + NAMESPACE_TO_PACKAGE_DIVIDER + "(.+)");
+
private final CodeWriter codeWriter;
- private static final Logger logger = LoggerFactory
- .getLogger(JMXGenerator.class);
private Map<String, String> namespaceToPackageMapping;
private File resourceBaseDir;
private File projectBaseDir;
private boolean generateModuleFactoryFile = true;
public JMXGenerator() {
- this.codeWriter = new FreeMarkerCodeWriterImpl();
+ this(new CodeWriter());
}
- public JMXGenerator(CodeWriter codeWriter) {
+ public JMXGenerator(final CodeWriter codeWriter) {
this.codeWriter = codeWriter;
}
@Override
- public Collection<File> generateSources(SchemaContext context,
- File outputBaseDir, Set<Module> yangModulesInCurrentMavenModule) {
+ public Collection<File> generateSources(final SchemaContext context,
+ final File outputBaseDir, final Set<Module> yangModulesInCurrentMavenModule) {
Preconditions.checkArgument(context != null, "Null context received");
Preconditions.checkArgument(outputBaseDir != null,
"Null outputBaseDir received");
Preconditions
- .checkArgument(namespaceToPackageMapping != null && !namespaceToPackageMapping.isEmpty(),
+ .checkArgument((this.namespaceToPackageMapping != null) && !this.namespaceToPackageMapping.isEmpty(),
"No namespace to package mapping provided in additionalConfiguration");
- packageTranslator = new PackageTranslator(namespaceToPackageMapping);
+ final PackageTranslator packageTranslator = new PackageTranslator(this.namespaceToPackageMapping);
- if (!outputBaseDir.exists())
+ if (!outputBaseDir.exists()) {
outputBaseDir.mkdirs();
+ }
- GeneratedFilesTracker generatedFiles = new GeneratedFilesTracker();
+ final GeneratedFilesTracker generatedFiles = new GeneratedFilesTracker();
// create SIE structure qNamesToSIEs
- Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
+ final Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
- Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
- for (Module module : context.getModules()) {
- String packageName = packageTranslator.getPackageName(module);
- Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
+ final Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
+ for (final Module module : context.getModules()) {
+ final String packageName = packageTranslator.getPackageName(module);
+ final Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
.create(module, packageName, knownSEITracker);
- for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
+ for (final Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
.entrySet()) {
// merge value into qNamesToSIEs
- if (qNamesToSIEs.containsKey(sieEntry.getKey()) == false) {
- qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue());
- } else {
+ if (qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue()) != null) {
throw new IllegalStateException(
- "Cannot add two SIE with same qname "
+ "Cannot add two SIE with same qname "
+ sieEntry.getValue());
}
}
if (yangModulesInCurrentMavenModule.contains(module)) {
// write this sie to disk
- for (ServiceInterfaceEntry sie : namesToSIEntries.values()) {
+ for (final ServiceInterfaceEntry sie : namesToSIEntries.values()) {
try {
- generatedFiles.addFile(codeWriter.writeSie(sie,
+ generatedFiles.addFile(this.codeWriter.writeSie(sie,
outputBaseDir));
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new RuntimeException(
"Error occurred during SIE source generate phase",
e);
}
}
- File mainBaseDir = concatFolders(projectBaseDir, "src", "main", "java");
- Preconditions.checkNotNull(resourceBaseDir,
+ final File mainBaseDir = concatFolders(this.projectBaseDir, "src", "main", "java");
+ Preconditions.checkNotNull(this.resourceBaseDir,
"resource base dir attribute was null");
- StringBuffer fullyQualifiedNamesOfFactories = new StringBuffer();
+ final StringBuilder fullyQualifiedNamesOfFactories = new StringBuilder();
// create MBEs
- for (Module module : yangModulesInCurrentMavenModule) {
- String packageName = packageTranslator.getPackageName(module);
- Map<String /* MB identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
+ for (final Module module : yangModulesInCurrentMavenModule) {
+ final String packageName = packageTranslator.getPackageName(module);
+ final Map<String /* MB identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
.create(module, qNamesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl(context)),
packageName);
- for (Entry<String, ModuleMXBeanEntry> mbeEntry : namesToMBEs
+ for (final Entry<String, ModuleMXBeanEntry> mbeEntry : namesToMBEs
.entrySet()) {
- ModuleMXBeanEntry mbe = mbeEntry.getValue();
+ final ModuleMXBeanEntry mbe = mbeEntry.getValue();
try {
- List<File> files1 = codeWriter.writeMbe(mbe, outputBaseDir,
- mainBaseDir, resourceBaseDir);
+ final List<File> files1 = this.codeWriter.writeMbe(mbe, outputBaseDir,
+ mainBaseDir);
generatedFiles.addFile(files1);
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new RuntimeException(
"Error occurred during MBE source generate phase",
e);
}
}
// create ModuleFactory file if needed
- if (fullyQualifiedNamesOfFactories.length() > 0
- && generateModuleFactoryFile) {
- File serviceLoaderFile = JMXGenerator.concatFolders(
- resourceBaseDir, "META-INF", "services",
+ if ((fullyQualifiedNamesOfFactories.length() > 0)
+ && this.generateModuleFactoryFile) {
+ final File serviceLoaderFile = JMXGenerator.concatFolders(
+ this.resourceBaseDir, "META-INF", "services",
ModuleFactory.class.getName());
// if this file does not exist, create empty file
serviceLoaderFile.getParentFile().mkdirs();
try {
serviceLoaderFile.createNewFile();
- FileUtils.write(serviceLoaderFile,
- fullyQualifiedNamesOfFactories.toString());
- } catch (IOException e) {
- String message = "Cannot write to " + serviceLoaderFile;
- logger.error(message);
+ Files.write(fullyQualifiedNamesOfFactories.toString(), serviceLoaderFile, StandardCharsets.UTF_8);
+ } catch (final IOException e) {
+ final String message = "Cannot write to " + serviceLoaderFile;
+ LOG.error(message, e);
throw new RuntimeException(message, e);
}
}
return generatedFiles.getFiles();
}
- static File concatFolders(File projectBaseDir, String... folderNames) {
- StringBuilder b = new StringBuilder();
- for (String folder : folderNames) {
- b.append(folder);
- b.append(File.separator);
+ @VisibleForTesting
+ static File concatFolders(final File projectBaseDir, final String... folderNames) {
+ File result = projectBaseDir;
+ for (final String folder: folderNames) {
+ result = new File(result, folder);
}
- return new File(projectBaseDir, b.toString());
+ return result;
}
@Override
- public void setAdditionalConfig(Map<String, String> additionalCfg) {
- if (logger != null)
- logger.debug(getClass().getCanonicalName(),
- ": Additional configuration received: ",
- additionalCfg.toString());
+ public void setAdditionalConfig(final Map<String, String> additionalCfg) {
+ LOG.debug("{}: Additional configuration received: {}", getClass().getCanonicalName(), additionalCfg);
this.namespaceToPackageMapping = extractNamespaceMapping(additionalCfg);
this.generateModuleFactoryFile = extractModuleFactoryBoolean(additionalCfg);
}
- private boolean extractModuleFactoryBoolean(
- Map<String, String> additionalCfg) {
- String bool = additionalCfg.get(MODULE_FACTORY_FILE_BOOLEAN);
- if (bool == null)
- return true;
- if (bool.equals("false"))
- return false;
- return true;
- }
-
- @Override
- public void setLog(Log log) {
- StaticLoggerBinder.getSingleton().setLog(log);
+ private static boolean extractModuleFactoryBoolean(final Map<String, String> additionalCfg) {
+ final String bool = additionalCfg.get(MODULE_FACTORY_FILE_BOOLEAN);
+ return !"false".equals(bool);
}
private static Map<String, String> extractNamespaceMapping(
- Map<String, String> additionalCfg) {
- Map<String, String> namespaceToPackage = Maps.newHashMap();
- for (String key : additionalCfg.keySet()) {
+ final Map<String, String> additionalCfg) {
+ final Map<String, String> namespaceToPackage = Maps.newHashMap();
+ for (final String key : additionalCfg.keySet()) {
if (key.startsWith(NAMESPACE_TO_PACKAGE_PREFIX)) {
- String mapping = additionalCfg.get(key);
- NamespaceMapping mappingResolved = extractNamespaceMapping(mapping);
+ final String mapping = additionalCfg.get(key);
+ final NamespaceMapping mappingResolved = extractNamespaceMapping(mapping);
namespaceToPackage.put(mappingResolved.namespace,
mappingResolved.packageName);
}
return namespaceToPackage;
}
- static Pattern namespaceMappingPattern = Pattern.compile("(.+)"
- + NAMESPACE_TO_PACKAGE_DIVIDER + "(.+)");
-
- private static NamespaceMapping extractNamespaceMapping(String mapping) {
- Matcher matcher = namespaceMappingPattern.matcher(mapping);
- Preconditions
- .checkArgument(matcher.matches(), String.format("Namespace to package mapping:%s is in invalid " +
- "format, requested format is: %s", mapping, namespaceMappingPattern));
+ private static NamespaceMapping extractNamespaceMapping(final String mapping) {
+ final Matcher matcher = NAMESPACE_MAPPING_PATTERN.matcher(mapping);
+ Preconditions.checkArgument(matcher.matches(),
+ "Namespace to package mapping:%s is in invalid format, requested format is: %s",
+ mapping, NAMESPACE_MAPPING_PATTERN);
return new NamespaceMapping(matcher.group(1), matcher.group(2));
}
- private static class NamespaceMapping {
- public NamespaceMapping(String namespace, String packagename) {
- this.namespace = namespace;
- this.packageName = packagename;
- }
-
- private final String namespace, packageName;
- }
-
@Override
- public void setResourceBaseDir(File resourceDir) {
+ public void setResourceBaseDir(final File resourceDir) {
this.resourceBaseDir = resourceDir;
}
@Override
- public void setMavenProject(MavenProject project) {
+ public void setMavenProject(final MavenProject project) {
this.projectBaseDir = project.getBasedir();
-
- if (logger != null)
- logger.debug(getClass().getCanonicalName(), " project base dir: ",
- projectBaseDir);
+ LOG.debug("{}: project base dir: {}", getClass().getCanonicalName(), this.projectBaseDir);
}
@VisibleForTesting
static class GeneratedFilesTracker {
private final Set<File> files = Sets.newHashSet();
- void addFile(File file) {
- if (files.contains(file)) {
- List<File> undeletedFiles = Lists.newArrayList();
- for (File presentFile : files) {
- if (presentFile.delete() == false) {
+ void addFile(final File file) {
+ if (this.files.contains(file)) {
+ final List<File> undeletedFiles = Lists.newArrayList();
+ for (final File presentFile : this.files) {
+ if (!presentFile.delete()) {
undeletedFiles.add(presentFile);
}
}
- if (undeletedFiles.isEmpty() == false) {
- logger.error(
+ if (!undeletedFiles.isEmpty()) {
+ LOG.error(
"Illegal state occurred: Unable to delete already generated files, undeleted files: {}",
undeletedFiles);
}
"Name conflict in generated files, file" + file
+ " present twice");
}
- files.add(file);
+ this.files.add(file);
}
- void addFile(Collection<File> files) {
- for (File file : files) {
+ void addFile(final Collection<File> files) {
+ for (final File file : files) {
addFile(file);
}
}
public Set<File> getFiles() {
- return files;
+ return this.files;
}
}
}