Kirk Rader  1.0-SNAPSHOT
Public Member Functions | Private Member Functions | Private Attributes | List of all members
us.rader.logging.statuscodes.maven.StatusCodesMojo Class Reference

Include logging message properties resources in the output of the build. More...

Inheritance diagram for us.rader.logging.statuscodes.maven.StatusCodesMojo:
Inheritance graph

Public Member Functions

void execute () throws MojoExecutionException
 Extract a properties file using MonitoredStatusCodeInfoList and include it as a resource. More...
 

Private Member Functions

void createAopFile (final File file, final Set< Package > packages) throws IOException
 Write META-INF/aop.xml if and only if aspects were specified in the POM. More...
 
Properties extractLogMessages (final File directory, final Set< Package > packages) throws MojoExecutionException
 Extract log message properties from the loose class files in the given directory and its sub-directories. More...
 
Set< URL > getProjectDependencies () throws MalformedURLException
 
void loadClasses (final Set< String > classNames, final Set< URL > dependencies, final Set< Class<?>> classes, final Set< Package > packages) throws ClassNotFoundException, IOException
 
void populateParametersForClassLoader (final int prefixLength, final File directory, final Set< String > classNames, final Set< URL > dependencies) throws IOException
 Populate two sets: the class files contained in a given directory and the dependency URL's necessary to load them. More...
 
void writeAopFile (final File file, final Set< Package > packages) throws IOException
 Called by createAopFile after all error checking and pre-conditions have been satisfied. More...
 
void writeElement (final XMLStreamWriter writer, final String tag, final String attribute, final String value) throws IOException
 

Private Attributes

String [] aspects
 Aspect classes to specify in aop.xml. More...
 
String [] weaverExclusions
 Exclusions to specify in aop.xml. More...
 
String classes
 The directory from which to load class files to inspect. More...
 
MavenProject project
 The POM contents. More...
 
String resource
 The path name for the resource file to generate. More...
 

Detailed Description

Include logging message properties resources in the output of the build.

See also
MonitoredStatusCodeInfoList

Definition at line 50 of file StatusCodesMojo.java.

Member Function Documentation

◆ createAopFile()

void us.rader.logging.statuscodes.maven.StatusCodesMojo.createAopFile ( final File  file,
final Set< Package >  packages 
) throws IOException
private

Write META-INF/aop.xml if and only if aspects were specified in the POM.

Parameters
fileThe path name for the AOP configuration file
packagesThe set of packages to include when weaving
Exceptions
IOExceptionThrown if an error occurs

Definition at line 141 of file StatusCodesMojo.java.

141  {
142 
143  if (aspects == null || aspects.length == 0) {
144 
145  return;
146  }
147 
148  final File metaDirectory = file.getParentFile();
149 
150  if (!(metaDirectory.exists() || metaDirectory.mkdirs())) {
151 
152  throw new IOException(String.format("failed to create directory %s", metaDirectory.getAbsolutePath()));
153 
154  }
155 
156  writeAopFile(file, packages);
157 
158  }
void writeAopFile(final File file, final Set< Package > packages)
Called by createAopFile after all error checking and pre-conditions have been satisfied.
String [] aspects
Aspect classes to specify in aop.xml.

◆ execute()

void us.rader.logging.statuscodes.maven.StatusCodesMojo.execute ( ) throws MojoExecutionException

Extract a properties file using MonitoredStatusCodeInfoList and include it as a resource.

Definition at line 89 of file StatusCodesMojo.java.

89  {
90 
91  try {
92 
93  final File classesDirectory = new File(classes).getCanonicalFile();
94  final Set<Package> packages = new HashSet<>();
95  final Properties properties = extractLogMessages(classesDirectory, packages);
96  final File resourceFile = new File(resource).getCanonicalFile();
97  final File resourceDirectory = resourceFile.getParentFile();
98 
99  if (!(resourceDirectory.exists() || resourceDirectory.mkdirs())) {
100 
101  throw new MojoExecutionException(
102  String.format("failed to create directory %s", resourceDirectory.getAbsolutePath()));
103 
104  }
105 
106  if (resourceFile.exists() && !resourceFile.delete()) {
107 
108  throw new IOException("error deleting " + resourceFile.getAbsolutePath());
109 
110  }
111 
112  try (FileOutputStream stream = new FileOutputStream(resourceFile)) {
113 
114  properties.store(stream, "Generated log messages -- DO NOT EDIT");
115 
116  }
117 
118  final File metaDirectory = new File(classesDirectory, "META-INF");
119  createAopFile(new File(metaDirectory, "aop.xml"), packages);
120 
121  } catch (final IOException e) {
122 
123  throw new MojoExecutionException(e.getMessage(), e);
124 
125  }
126  }
Properties extractLogMessages(final File directory, final Set< Package > packages)
Extract log message properties from the loose class files in the given directory and its sub-director...
void createAopFile(final File file, final Set< Package > packages)
Write META-INF/aop.xml if and only if aspects were specified in the POM.
String classes
The directory from which to load class files to inspect.
String resource
The path name for the resource file to generate.

◆ extractLogMessages()

Properties us.rader.logging.statuscodes.maven.StatusCodesMojo.extractLogMessages ( final File  directory,
final Set< Package >  packages 
) throws MojoExecutionException
private

Extract log message properties from the loose class files in the given directory and its sub-directories.

Parameters
directoryThe directory containing the class files
packagesThe loaded packages (output)
Returns
The Properties
Exceptions
MojoExecutionExceptionThrown if an error occurs

Definition at line 175 of file StatusCodesMojo.java.

176  {
177 
178  try {
179 
180  // suppress an idiotic SonarQube rule since URLClassLoader requires
181  // URL's -- as its name implies
182  final Set<URL> dependencies = getProjectDependencies(); // NOSONAR
183  final Set<String> classNames = new HashSet<>();
184  populateParametersForClassLoader(directory.getAbsolutePath().length() + 1, directory, classNames,
185  dependencies);
186  final Set<Class<?>> loadedClasses = new HashSet<>();
187  loadClasses(classNames, dependencies, loadedClasses, packages);
188  final Class<?>[] array = new Class<?>[loadedClasses.size()];
189  loadedClasses.toArray(array);
190  final MonitoredStatusCodeInfoList statusCodes = new MonitoredStatusCodeInfoList(array);
191  return statusCodes.toProperties();
192 
193  } catch (IOException | ReflectiveOperationException e) {
194 
195  throw new MojoExecutionException(e.getMessage(), e);
196 
197  }
198  }
void populateParametersForClassLoader(final int prefixLength, final File directory, final Set< String > classNames, final Set< URL > dependencies)
Populate two sets: the class files contained in a given directory and the dependency URL&#39;s necessary ...
void loadClasses(final Set< String > classNames, final Set< URL > dependencies, final Set< Class<?>> classes, final Set< Package > packages)

◆ getProjectDependencies()

Set<URL> us.rader.logging.statuscodes.maven.StatusCodesMojo.getProjectDependencies ( ) throws MalformedURLException
private
Returns
The set of URL's for the dependencies listed in the POM
Exceptions
MalformedURLExceptionThrown if there is a bug in the JVM

Definition at line 206 of file StatusCodesMojo.java.

206  {
207 
208  // suppress an idiotic SonarQube rule since URLClassLoader requires
209  // URL's -- as its name implies
210  final Set<URL> dependencies = new HashSet<>(); // NOSONAR
211 
212  for (final Object object : project.getArtifacts()) {
213 
214  // evidently those responsible for inflicting Maven on the world
215  // are unaware of generic types
216  final Artifact artifact = (Artifact) object;
217  final File jar = artifact.getFile();
218 
219  if (jar != null) {
220 
221  dependencies.add(jar.toURI().toURL());
222 
223  }
224  }
225 
226  return dependencies;
227 
228  }

◆ loadClasses()

void us.rader.logging.statuscodes.maven.StatusCodesMojo.loadClasses ( final Set< String >  classNames,
final Set< URL >  dependencies,
final Set< Class<?>>  classes,
final Set< Package >  packages 
) throws ClassNotFoundException, IOException
private
Parameters
classNamesThe names of the classes to load
dependenciesThe dependency URL's
classesThe set of loaded classes (output)
packagesThe set of packages for all the specified classes (output)
Exceptions
ClassNotFoundExceptionThrown if a dependency is not satisfied
IOExceptionThrown if there is an I/O error loading a class file

Definition at line 249 of file StatusCodesMojo.java.

250  {
251 
252  final URL[] classpath = new URL[dependencies.size()];
253  dependencies.toArray(classpath);
254 
255  try (URLClassLoader loader = new URLClassLoader(classpath, StatusCodesMojo.class.getClassLoader())) {
256 
257  for (final String name : classNames) {
258 
259  final Class<?> cls = loader.loadClass(name);
260  classes.add(cls);
261  packages.add(cls.getPackage());
262 
263  }
264  }
265  }
String classes
The directory from which to load class files to inspect.

◆ populateParametersForClassLoader()

void us.rader.logging.statuscodes.maven.StatusCodesMojo.populateParametersForClassLoader ( final int  prefixLength,
final File  directory,
final Set< String >  classNames,
final Set< URL >  dependencies 
) throws IOException
private

Populate two sets: the class files contained in a given directory and the dependency URL's necessary to load them.

This recursively walks the directory tree adding the file-system URL for the current directory to the set of dependencies and the file system path for each _.class_ file to the set of class file paths.

Parameters
prefixLengthThe length of the prefix to strip from each class file path when converting it to a class name string
directoryThe current directory to add to the set of dependencies and to search for class files
classNamesThe set of class names to load (output)
dependenciesThe set of dependencies (output)
Exceptions
IOExceptionThrown if there is an error while listing the contents of a directory

Definition at line 293 of file StatusCodesMojo.java.

294  {
295 
296  dependencies.add(directory.toURI().toURL());
297 
298  for (final File file : directory.listFiles()) {
299 
300  if (file.isDirectory()) {
301 
302  populateParametersForClassLoader(prefixLength, file, classNames, dependencies);
303 
304  } else if (file.getName().toLowerCase().endsWith(".class")) {
305 
306  // convert file name to class name...
307  final String name = file.getAbsolutePath();
308  classNames.add(name.substring(prefixLength, name.length() - 6).replace(File.separatorChar, '.'));
309 
310  }
311  }
312  }
void populateParametersForClassLoader(final int prefixLength, final File directory, final Set< String > classNames, final Set< URL > dependencies)
Populate two sets: the class files contained in a given directory and the dependency URL&#39;s necessary ...

◆ writeAopFile()

void us.rader.logging.statuscodes.maven.StatusCodesMojo.writeAopFile ( final File  file,
final Set< Package >  packages 
) throws IOException
private

Called by createAopFile after all error checking and pre-conditions have been satisfied.

Extracted to a separate routine only because of ill-conceived SonarQube "cyclomatic complexity" rule.

Parameters
fileThe file to write
packagesThe packages in which to inject aspects
Exceptions
IOExceptionThrown if an error occurs

Definition at line 330 of file StatusCodesMojo.java.

330  {
331 
332  try (FileOutputStream stream = new FileOutputStream(file)) {
333 
334  final XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(stream);
335  writer.writeStartDocument("UTF-8", "1.0");
336  writer.writeStartElement("aspectj");
337  writer.writeStartElement("aspects");
338 
339  for (final String aspect : aspects) {
340 
341  writeElement(writer, "aspect", "name", aspect);
342 
343  }
344 
345  writer.writeEndElement(); // aspects
346  writer.writeStartElement("weaver");
347 
348  for (final Package pkg : packages) {
349 
350  writeElement(writer, "include", "within", pkg.getName() + ".*");
351 
352  }
353 
354  if (weaverExclusions != null && weaverExclusions.length > 0) {
355 
356  for (final String exclude : weaverExclusions) {
357 
358  writeElement(writer, "exclude", "within", exclude);
359 
360  }
361  }
362 
363  writer.writeEndElement(); // weaver
364  writer.writeEndElement(); // aspectj
365  writer.writeEndDocument();
366 
367  } catch (XMLStreamException | FactoryConfigurationError e) {
368 
369  throw new IOException(e);
370 
371  }
372  }
String [] weaverExclusions
Exclusions to specify in aop.xml.
void writeElement(final XMLStreamWriter writer, final String tag, final String attribute, final String value)
String [] aspects
Aspect classes to specify in aop.xml.

◆ writeElement()

void us.rader.logging.statuscodes.maven.StatusCodesMojo.writeElement ( final XMLStreamWriter  writer,
final String  tag,
final String  attribute,
final String  value 
) throws IOException
private
Parameters
writerXML output stream
tagElement name
attributeAttribute name
valueAttribute value
Exceptions
IOExceptionThrown if an error occurs

Definition at line 390 of file StatusCodesMojo.java.

391  {
392 
393  try {
394 
395  writer.writeStartElement(tag);
396  writer.writeAttribute(attribute, value);
397  writer.writeEndElement();
398 
399  } catch (final XMLStreamException e) {
400 
401  throw new IOException(e);
402 
403  }
404  }

Member Data Documentation

◆ aspects

String [] us.rader.logging.statuscodes.maven.StatusCodesMojo.aspects
private

Aspect classes to specify in aop.xml.

See createAopFile

Definition at line 58 of file StatusCodesMojo.java.

◆ classes

String us.rader.logging.statuscodes.maven.StatusCodesMojo.classes
private

The directory from which to load class files to inspect.

Definition at line 70 of file StatusCodesMojo.java.

◆ project

MavenProject us.rader.logging.statuscodes.maven.StatusCodesMojo.project
private

The POM contents.

Definition at line 76 of file StatusCodesMojo.java.

◆ resource

String us.rader.logging.statuscodes.maven.StatusCodesMojo.resource
private

The path name for the resource file to generate.

Definition at line 82 of file StatusCodesMojo.java.

◆ weaverExclusions

String [] us.rader.logging.statuscodes.maven.StatusCodesMojo.weaverExclusions
private

Exclusions to specify in aop.xml.

Definition at line 64 of file StatusCodesMojo.java.


The documentation for this class was generated from the following file: