Skip to content

Instantly share code, notes, and snippets.

@alexandru
Created January 6, 2016 12:58
Show Gist options
  • Select an option

  • Save alexandru/52aea1ff8e012176915e to your computer and use it in GitHub Desktop.

Select an option

Save alexandru/52aea1ff8e012176915e to your computer and use it in GitHub Desktop.
For generating classes from WSDL specifications using Apache CXF
cxf.wsdlFiles := Seq(cxf.Wsdl(file("conf/wsdl/RDMService.wsdl"),
Seq("-p", "com.yours.generated"), None))
compile in Compile <<= (compile in Compile).dependsOn(cxf.wsdl2java)
import sbt._
import sbt.classpath.ClasspathUtilities
import sbt.Keys._
import java.io.File
import scala.util.control.NonFatal
object WDSLPlugin extends Plugin {
object cxf {
val Config = config("cxf").hide
val wsdl2java = TaskKey[Seq[File]]("wsdl2java", "Generates java files from wsdls")
val wsdlFiles = SettingKey[Seq[Wsdl]]("wsdlFiles", "WSDL files to generate java files from")
case class Wsdl(file: File, args: Seq[String], key: Option[String] = None) {
val id = key.getOrElse(args.mkString.hashCode.abs).toString
def outputDirectory(basedir: File) =
new File(basedir, id).getAbsoluteFile
}
val settings = Seq(
ivyConfigurations += Config,
version in Config := "3.1.4",
libraryDependencies <++= (version in Config)(version => Seq[ModuleID](
"org.apache.cxf" % "cxf-tools-wsdlto-core" % version % Config.name,
"org.apache.cxf" % "cxf-tools-wsdlto-databinding-jaxb" % version % Config.name,
"org.apache.cxf" % "cxf-tools-wsdlto-frontend-jaxws" % version % Config.name
)),
wsdlFiles := Nil,
managedClasspath in wsdl2java <<= (classpathTypes in wsdl2java, update) map { (ct, report) =>
Classpaths.managedJars(Config, ct, report)
},
sourceManaged in Config <<= sourceManaged(_ / "cxf"),
managedSourceDirectories in Compile <++= (wsdlFiles, sourceManaged in Config) { (wsdls, basedir) =>
wsdls map { _.outputDirectory(basedir) }
},
wsdl2java := {
val logger = streams.value.log
val wsdls = wsdlFiles.value
val basedir = (sourceManaged in Config).value
val cp = (managedClasspath in wsdl2java).value
val classpath = cp.files
wsdls.flatMap { wsdl =>
val output = wsdl.outputDirectory(basedir)
if(wsdl.file.lastModified() > output.lastModified()) {
val args = Seq("-d", output.getAbsolutePath) ++ wsdl.args :+ wsdl.file.getAbsolutePath
callWsdl2java(wsdl.id, output, args, classpath, logger)
}
val files = (output ** "*.java").get
files
}
},
sourceGenerators in Compile <+= wsdl2java
)
def callWsdl2java(id: String, output: File, args: Seq[String], classpath: Seq[File], logger: Logger): Unit = {
logger.info("WSDL: id=" + id + ", args=" + args)
logger.info("Removing output directory...")
IO.delete(output)
logger.info("Compiling WSDL...")
val start = System.currentTimeMillis()
val classLoader = ClasspathUtilities.toLoader(classpath)
val WSDLToJava = classLoader.loadClass("org.apache.cxf.tools.wsdlto.WSDLToJava")
val ToolContext = classLoader.loadClass("org.apache.cxf.tools.common.ToolContext")
val constructor = WSDLToJava.getConstructor(classOf[Array[String]])
val run = WSDLToJava.getMethod("run", ToolContext)
val oldContextClassLoader = Thread.currentThread.getContextClassLoader
try {
// to satisfy the jaxb reflection madness classLoader requirements
Thread.currentThread.setContextClassLoader(classLoader)
val instance = constructor.newInstance(args.toArray)
run.invoke(instance, ToolContext.newInstance().asInstanceOf[AnyRef])
} catch {
case NonFatal(ex) =>
logger.error(ex.getStackTraceString)
} finally {
val end = System.currentTimeMillis()
logger.info("Compiled WSDL in " + (end - start) + "ms.")
Thread.currentThread.setContextClassLoader(oldContextClassLoader)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment