A niechby to był taki malutki projekcik, jak ten mój, dzisiejszy do obrabiania XMLi. Nic nadzwyczajnego, ale czego oczekiwać od nowicjusza scalowego, który karierę w tym języku liczy w dniach (a nie tygodniach, czy miesiącach)?! Każdy przecież kiedyś był początkujący w rzeczach, w których teraz wiedzie prym. Ja właśnie zaczynam swoje pierwsze kroki w Scali i twory przypominają prawdziwe potwory, ale od czegoś zacząć należy!
Wierzę, że z pomocą Grześka, teamon'a oraz dmilith'a nauka Scali będzie tylko przyjemnością!
Pora na odsłonę mojego dzieła. Komentarze mile widziane.
package pl.japila.wli.transformations.control
import scala.xml.{ XML, Node, Elem }
import scala.xml.transform.{ RuleTransformer, RewriteRule }
object WLIControlMigrationMain {
// FIXME: Remove it once the script reads input args or we find them a better place
val pkg = "pl.japila.wli.transformations.control".replace(".", "/")
def main(args: Array[String]) {
// The file comes from the BPEL Exporter in WLI
val processCtrlXml = XML.load(getClass.getResourceAsStream(s"/${pkg}/process_ctrl.wsdl"))
val portType = (processCtrlXml \ "portType" \ "@name").text
// The file is ours - the template for a JMS import
val importXmlTemplate = XML.load(getClass.getResourceAsStream(s"/${pkg}/import-xml.template"))
// The file name and the name of the import component must be alike
val importComponentName = portType + "_MB_Publish_control"
println(s"+++\n+++ Save the following file as ${importComponentName}.import:\n+++")
println(importXmlTemplate.toString
.replace("{importComponentName}", importComponentName)
.replace("{portType}", portType))
println(s"+++\n+++ Save the following file as process.component:\n+++")
wireComponentWithImport(importComponentName)
}
def wireComponentWithImport(importComponentName: String) {
val processComponentXML = XML.load(getClass.getResourceAsStream(s"/${pkg}/process.component"))
val wire = XML.loadString(s"<wire target='${importComponentName}'/>")
val wiredProcessComponentXML = new RuleTransformer(
new AddChildrenTo("reference", wire))
.transform(processComponentXML).head
println(wiredProcessComponentXML)
}
// http://stackoverflow.com/questions/2199040/scala-xml-building-adding-children-to-existing-nodes
def addChild(n: Node, newChild: Node) = n match {
case Elem(prefix, label, attribs, scope, child @ _*) =>
Elem(prefix, label, attribs, scope, child ++ newChild: _*)
case _ => sys.error("Can only add children to elements!")
}
class AddChildrenTo(label: String, newChild: Node) extends RewriteRule {
override def transform(n: Node) = n match {
case Elem(_, `label`, _, _, _*) => addChild(n, newChild)
case _ => n
}
}
}
Gratuluję pierwszego projektu!
OdpowiedzUsuńKilka drobnych uwag:
W metodzie addChildrenTo możesz usunąć fragment "n @".
Możesz również zamienić case other => other na case _ => n (ale zapis z other może oczywiście zostać).
Zamiast XML.load i getResourceAsStream możesz użyć XML.loadFile i podać ścieżkę pliku po prostu.
Po toString nie potrzebujesz dodawać nawiasów ()
Dzięki Grzesiek.
UsuńOdnośnie zmian to:
-> n @ jest faktycznie nadmiarowe, bo skoro wpada w pierwszy case to już jest n-em. Skopiowałem z SO bez większego zastanowienia.
-> przyjmuję uwagę o case _. Zdaje się być idiomem, który przechwytuje wszystko pozostałe i taki jest właśnie zamiar tego wyrażenia.
-> XML.loadFile ładuje plik ze znanego miejsca w systemie plików. Na chwilę obecną odpada, bo nie obsługuję podawania plików z linii poleceń i pracuję wyłącznie z tymi, które znajdę na CLASSPATH. Stąd właśnie użycie XML.load(InputStream).
-> Z tymi nawiasami muszę sobie pożyć trochę, bo przy println ich nie chciałbym dawać, a muszą być, a w innych miejscach dodaję samoistnie.
Dzięki jeszcze raz za uwagi. Pomocne wielce!
p.s. Siedzę właśnie nad zipperami w Scali. Patrz http://en.wikipedia.org/wiki/Zipper_%28data_structure%29 oraz http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf. Widziałem to pierwszy raz przy nauce Clojure i teraz pojawiło się ponownie przy tym zadaniu w Scali. To mogłoby być ciekawym tematem na szkolenie/warsztaty z zaawansowanej Scali.
Poprawione! Jeszcze raz dziękuję za uwagę i uwagi :-)
Usuń