diff --git a/pom.xml b/pom.xml
index 4be3077..83255d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -104,6 +104,12 @@
${gson.version}
+
+ org.codehaus.plexus
+ plexus-resources
+ 1.3.0
+
+
diff --git a/src/main/java/biz/lermitage/oga/CheckMojo.kt b/src/main/java/biz/lermitage/oga/CheckMojo.kt
index 54c45d0..f4282be 100644
--- a/src/main/java/biz/lermitage/oga/CheckMojo.kt
+++ b/src/main/java/biz/lermitage/oga/CheckMojo.kt
@@ -5,15 +5,17 @@ import biz.lermitage.oga.cfg.IgnoreList
import biz.lermitage.oga.util.DefinitionsTools
import biz.lermitage.oga.util.IOTools
import biz.lermitage.oga.util.IgnoreListTools
+import org.apache.maven.execution.MavenSession
import org.apache.maven.plugin.AbstractMojo
import org.apache.maven.plugin.MojoExecutionException
+import org.apache.maven.plugins.annotations.Component
import org.apache.maven.plugins.annotations.Mojo
import org.apache.maven.plugins.annotations.Parameter
import org.apache.maven.project.MavenProject
+import org.codehaus.plexus.resource.ResourceManager
+import org.codehaus.plexus.resource.loader.FileResourceLoader
import org.codehaus.plexus.util.xml.pull.XmlPullParserException
-import java.io.File
import java.io.IOException
-import java.net.URL
import java.util.Optional
/**
@@ -60,6 +62,12 @@ class CheckMojo : AbstractMojo() {
@Parameter(property = "project", readonly = true)
var project: MavenProject? = null
+ @Parameter(defaultValue = "\${session}", required = true, readonly = true)
+ private var session: MavenSession? = null
+
+ @Component
+ private val locator: ResourceManager? = null
+
/**
* Execute goal.
*/
@@ -72,22 +80,25 @@ class CheckMojo : AbstractMojo() {
return
}
+ setUpLocator(locator!!)
+
try {
- val allDefinitions = mutableListOf(DefinitionsTools.loadDefinitionsFromUrl(ogDefinitionsUrl ?: DEFINITIONS_URL, log))
+ val allDefinitions = mutableListOf(DefinitionsTools.loadDefinitionsFromUrl(ogDefinitionsUrl ?: DEFINITIONS_URL, log, locator))
if (!ignoreUnofficialMigrations) {
- allDefinitions += DefinitionsTools.loadDefinitionsFromUrl(ogUnofficialDefinitionsUrl ?: UNOFFICIAL_DEFINITIONS_URL, log)
+ allDefinitions += DefinitionsTools.loadDefinitionsFromUrl(ogUnofficialDefinitionsUrl ?: UNOFFICIAL_DEFINITIONS_URL, log, locator)
}
// Load additional definitions if defined
- additionalDefinitionFiles!!.forEach { allDefinitions += DefinitionsTools.loadDefinitionsFromUrl(it, log) }
+ additionalDefinitionFiles!!.forEach { allDefinitions += DefinitionsTools.loadDefinitionsFromUrl(it, log, locator) }
var ignoreList = Optional.empty()
if (!ignoreListFile.isNullOrEmpty()) {
log.info("Loading ignore list from file $ignoreListFile")
- ignoreList = Optional.of(IOTools.readIgnoreList(File(ignoreListFile)))
+ // TODO given that we now support loading a file from classpath, file and URL we could consolidate configuration to definitions and suppressions (like PMD/Checkstyle)
+ ignoreList = Optional.of(IOTools.readIgnoreList(ignoreListFile, locator, log))
} else if (!ignoreListUrl.isNullOrEmpty()) {
log.info("Loading ignore list from url $ignoreListUrl")
- ignoreList = Optional.of(IOTools.readIgnoreList(URL(ignoreListUrl)))
+ ignoreList = Optional.of(IOTools.readIgnoreList(ignoreListUrl, locator, log))
}
val dependencies = DefinitionsTools.mapDependenciesToOgaDependencies(project!!.dependencies!!)
@@ -162,6 +173,19 @@ class CheckMojo : AbstractMojo() {
}
}
+ private fun setUpLocator(locator: ResourceManager) {
+ val searchPaths = listOf(
+ // 0. The locator will read from classpath and URL locations
+ // 1. in the directory of the current project's pom file - note: extensions might replace the pom file on the fly
+ project!!.file.parentFile.absolutePath,
+ // 2. in the current project's directory
+ project!!.basedir.absolutePath,
+ // 3. in the base directory - that's the directory of the initial pom requested to build, e.g. the root of a multi-module build
+ session!!.request!!.baseDirectory
+ )
+ searchPaths.forEach { searchPath -> locator.addSearchPath(FileResourceLoader.ID, searchPath) }
+ }
+
companion object {
private const val GITHUB_PRJ_RAW_URL = "https://raw.githubusercontent.com/jonathanlermitage/oga-maven-plugin/master/"
private const val DEFINITIONS_URL = GITHUB_PRJ_RAW_URL + "uc/og-definitions.json"
diff --git a/src/main/java/biz/lermitage/oga/util/DefinitionsTools.kt b/src/main/java/biz/lermitage/oga/util/DefinitionsTools.kt
index 9918ef5..1399827 100644
--- a/src/main/java/biz/lermitage/oga/util/DefinitionsTools.kt
+++ b/src/main/java/biz/lermitage/oga/util/DefinitionsTools.kt
@@ -4,6 +4,7 @@ import biz.lermitage.oga.Dependency
import biz.lermitage.oga.DependencyType
import biz.lermitage.oga.cfg.Definitions
import org.apache.maven.plugin.logging.Log
+import org.codehaus.plexus.resource.ResourceManager
/**
* Definitions tools.
@@ -12,9 +13,9 @@ import org.apache.maven.plugin.logging.Log
*/
object DefinitionsTools {
- fun loadDefinitionsFromUrl(url: String, log: Log): Definitions {
+ fun loadDefinitionsFromUrl(url: String, log: Log, locator: ResourceManager): Definitions {
log.info("Loading definitions from $url")
- val definitions = IOTools.readDefinitions(url)
+ val definitions = IOTools.readDefinitions(url, locator, log)
val nbDefinitions = definitions.migration?.size
var welcomeMsg = "Loaded $nbDefinitions definitions from '$url'"
diff --git a/src/main/java/biz/lermitage/oga/util/IOTools.kt b/src/main/java/biz/lermitage/oga/util/IOTools.kt
index 4f838ea..aa0e909 100644
--- a/src/main/java/biz/lermitage/oga/util/IOTools.kt
+++ b/src/main/java/biz/lermitage/oga/util/IOTools.kt
@@ -4,13 +4,15 @@ import biz.lermitage.oga.cfg.Definitions
import biz.lermitage.oga.cfg.IgnoreList
import com.google.gson.GsonBuilder
import org.apache.commons.io.FileUtils
-import java.io.BufferedReader
+import org.apache.maven.plugin.MojoExecutionException
+import org.apache.maven.plugin.logging.Log
+import org.codehaus.plexus.resource.ResourceManager
+import org.codehaus.plexus.resource.loader.FileResourceCreationException
+import org.codehaus.plexus.resource.loader.ResourceNotFoundException
import java.io.File
import java.io.IOException
-import java.io.InputStreamReader
-import java.net.HttpURLConnection
-import java.net.URL
-import java.util.regex.Pattern
+import java.nio.file.Files
+import kotlin.io.path.pathString
/**
* IO tools.
@@ -22,45 +24,33 @@ object IOTools {
private val GSON = GsonBuilder().create()
@Throws(IOException::class)
- fun readDefinitions(url: String): Definitions {
- return readFromLocation(url, Definitions::class.java)
+ fun readDefinitions(location: String, locator: ResourceManager, log: Log): Definitions {
+ return readFromLocation(location, locator, log, Definitions::class.java)
}
@Throws(IOException::class)
- fun readIgnoreList(url: URL): IgnoreList {
- val ignoreListAsString = readContent(url)
- return GSON.fromJson(ignoreListAsString, IgnoreList::class.java)
+ fun readIgnoreList(location: String, locator: ResourceManager, log: Log): IgnoreList {
+ return readFromLocation(location, locator, log, IgnoreList::class.java)
}
@Throws(IOException::class)
- fun readIgnoreList(file: File): IgnoreList {
- val ignoreListAsString = FileUtils.readFileToString(file, Charsets.UTF_8)
- return GSON.fromJson(ignoreListAsString, IgnoreList::class.java)
- }
-
- @Throws(IOException::class)
- private fun readFromLocation(location: String, clazz: Class): T {
- val uriRx: Pattern = Pattern.compile("^https?:.*", Pattern.CASE_INSENSITIVE)
- val asString = if (uriRx.matcher(location).matches()) {
- readContent(URL(location))
- } else {
- FileUtils.readFileToString(File(location), Charsets.UTF_8)
- }
+ private fun readFromLocation(location: String, locator: ResourceManager, log: Log, clazz: Class): T {
+ val file = locationToFile(location, locator, log)
+ val asString = FileUtils.readFileToString(file, Charsets.UTF_8)
return GSON.fromJson(asString, clazz)
}
- @Throws(IOException::class)
- private fun readContent(url: URL): String {
- val content = StringBuilder()
- val conn = url.openConnection() as HttpURLConnection
- conn.requestMethod = "GET"
- BufferedReader(InputStreamReader(conn.inputStream)).use { rd ->
- var line: String? = rd.readLine()
- while (line != null) {
- content.append(line)
- line = rd.readLine()
- }
+ @Throws(MojoExecutionException::class)
+ private fun locationToFile(location: String, locator: ResourceManager, log: Log): File {
+ try {
+ val resolvedLocation = Files.createTempFile("oga-", ".json")
+ log.debug("Resolved file from '$location' to '$resolvedLocation'")
+ return locator.getResourceAsFile(location, resolvedLocation.pathString)
+ ?: throw MojoExecutionException("Could not resolve $location")
+ } catch (e: ResourceNotFoundException) {
+ throw MojoExecutionException(e.message, e)
+ } catch (e: FileResourceCreationException) {
+ throw MojoExecutionException(e.message, e)
}
- return content.toString()
}
}