Commit 6a3ff7ca by Amelin Konstantin

Merge branch 'dev'

# Conflicts:
#	src/main/scala/Main.scala - fixed
parents f880bf0f a244794b
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
Запуск осуществляется из командной строки с двумя параметрами: путь к директории входящих сообщений, путь к директории сконвертированных сообщений. Запуск осуществляется из командной строки с двумя параметрами: путь к директории входящих сообщений, путь к директории сконвертированных сообщений.
Конвертер работает по принципу пакетного обработчика. Действие выполняется над всеми файлами, находящимися в директории входящих сообщений. Конвертер работает по принципу пакетного обработчика. Действие выполняется над всеми файлами, находящимися в директории входящих сообщений.
Поддерживается формат xml и zip (архив, cодержащий xml файлы). Поддерживается формат xml и zip (архив, cодержащий xml файлы).
Лог файл с отчетом о конвертации сохраняется в директории сконвертированных сообщений. Лог файл с отчетом о конвертации сохраняется в директории входящих сообщений.
Запуск. Запуск.
......
...@@ -3,7 +3,7 @@ import com.typesafe.config.{Config, ConfigFactory} ...@@ -3,7 +3,7 @@ import com.typesafe.config.{Config, ConfigFactory}
import scala.xml._ import scala.xml._
import java.nio.file.{Files, Paths, StandardOpenOption} import java.nio.file.{Files, Paths, StandardOpenOption}
import java.io.{File, FileInputStream, InputStream} import java.io.{File, FileInputStream, InputStream}
import java.util.zip.ZipFile import java.util.zip.{ZipEntry, ZipFile}
import java.time.LocalDateTime import java.time.LocalDateTime
import scala.util.{Failure, Success, Try} import scala.util.{Failure, Success, Try}
...@@ -35,78 +35,108 @@ object Main { ...@@ -35,78 +35,108 @@ object Main {
.filter { .filter {
!_.isDirectory !_.isDirectory
} }
.sortBy {
_.lastModified
}
val start = LocalDateTime.now().toString val start = LocalDateTime.now.toString.replace(":", ".")
val sourceNameValidated = s"${args(0)}/${start}_validated"
val sourceValidated = new File(sourceNameValidated)
val sourceNameNotValidated = s"${args(0)}/${start}_not_validated"
val sourceNotValidated = new File(sourceNameNotValidated)
val sourceNameError = s"${args(0)}/${start}_error"
val sourceError = new File(sourceNameError)
val outputNameValidated = s"${args(1)}/${start}_validated"
val outputValidated = new File(outputNameValidated)
val outputNameNotValidated = s"${args(1)}/${start}_not_validated"
val outputNotValidated = new File(outputNameNotValidated)
if (sourceValidated.mkdir
&& sourceNotValidated.mkdir
&& sourceError.mkdir
&& outputValidated.mkdir
&& outputNotValidated.mkdir) {
val sourceArray = {
for (f <- files) yield {
val name = f.getName
val ext = name.split('.').last.toLowerCase
val successSourcesName = s"${args(0)}/${start}_success" if (ext == "zip")
val successSources = new File(successSourcesName) Try {
val errorSourcesName = s"${args(0)}/${start}_error" val zip = new ZipFile(f)
val errorSources = new File(errorSourcesName)
if (successSources.mkdir() && errorSources.mkdir()) { zip.stream.toArray
.map {
z => z.asInstanceOf[ZipEntry]
}
.map {
e =>
FileEntry(
s"${name}_${e.getName}",
//e.getName,
e.getLastModifiedTime.toMillis,
Some(zip.getInputStream(e)),
zip.getInputStream(e),
None)
}
} match {
case Success(v) =>
v
case Failure(ex) =>
Array(FileEntry(name, f.lastModified, None, new FileInputStream(f), Some(ex.toString)))
}
else
Array(FileEntry(name, f.lastModified, Some(new FileInputStream(f)), new FileInputStream(f), None))
}
}
.flatten
.sortWith { (a, b) => (a.modified == b.modified && a.name <= b.name) || (a.modified < b.modified) }
for (f <- files) {
val fSourceName = f.getName
val fSourceNameArray = fSourceName.split('.')
val fSourceNameExtension = fSourceNameArray.last.toLowerCase
val now = LocalDateTime.now().toString
if (fSourceNameExtension == "zip") Try { Try {
val fZip = new ZipFile(f) for (f <- sourceArray) {
val fZipEntries = fZip.entries val now = LocalDateTime.now.toString
while (fZipEntries.hasMoreElements) { f.msg match {
val e = fZipEntries.nextElement case Some(msg) =>
if (!e.isDirectory) { logString += s"'$now'\nImpossible to process '${f.name}': $msg\n\n"
val fZipEntryName = e.getName Files.copy(f.streamMove, Paths.get(sourceNameError, f.name))
val nowForZip = LocalDateTime.now().toString
case None =>
Try { Try {
convert( convert(
fZip.getInputStream(e), f.streamConvert.get,
s"${fSourceName}_$fZipEntryName", f.name,
s"Converted_${fSourceName}_$fZipEntryName", s"converted_${f.name}",
nsdXmlValid, nsdXmlValid,
rtsXmlValid, rtsXmlValid,
p) p)
} match { } match {
case Success((oXml, ti)) if ti.contains("isn`t wellformed or invalid") =>
XML.save(
Paths.get(outputNameNotValidated, s"converted_${f.name}").toString,
oXml,
xmlDecl = true
)
logString += s"'$now'\n$ti"
Files.copy(f.streamMove, Paths.get(sourceNameNotValidated, f.name))
case Success((oXml, ti)) => case Success((oXml, ti)) =>
XML.save(Paths.get(args(1), s"Converted_${fSourceName}_$fZipEntryName").toString, oXml, xmlDecl = true) XML.save(
logString += s"$nowForZip\n$ti" Paths.get(outputNameValidated, s"converted_${f.name}").toString,
Files.copy(fZip.getInputStream(e), Paths.get(successSourcesName, s"${fSourceName}_$fZipEntryName")) oXml,
xmlDecl = true
)
logString += s"'$now'\n$ti"
Files.copy(f.streamMove, Paths.get(sourceNameValidated, f.name))
case Failure(ex) => case Failure(ex) =>
logString += s"'$nowForZip\nImpossible to convert '${fSourceName}_$fZipEntryName': ${ex.getMessage}\n\n" logString += s"'$now'\nImpossible to convert '${f.name}': ${ex.toString}\n\n"
Files.copy(fZip.getInputStream(e), Paths.get(errorSourcesName, s"${fSourceName}_$fZipEntryName")) Files.copy(f.streamMove, Paths.get(sourceNameError, f.name))
} }
}
} }
} match {
case Success(_) =>
case Failure(ex) => logString += s"'$now\nImpossible to convert '$fSourceName': ${ex.getMessage}\n\n"
} }
else Try {
convert(
new FileInputStream(f),
s"$fSourceName",
s"Converted_$fSourceName",
nsdXmlValid,
rtsXmlValid,
p)
} match {
case Success((oXml, ti)) =>
XML.save(Paths.get(args(1), s"Converted_$fSourceName").toString, oXml, xmlDecl = true)
logString += s"$now\n$ti"
Files.copy(f.toPath, Paths.get(successSourcesName, f.getName))
case Failure(ex) =>
logString += s"'$now\nImpossible to convert '$fSourceName': ${ex.getMessage}\n\n"
Files.copy(f.toPath, Paths.get(errorSourcesName, f.getName))
}
}
Try {
files.foreach { _.delete } files.foreach { _.delete }
Files.write( Files.write(
...@@ -115,18 +145,23 @@ object Main { ...@@ -115,18 +145,23 @@ object Main {
StandardOpenOption.CREATE, StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING) StandardOpenOption.TRUNCATE_EXISTING)
if (successSources.listFiles.nonEmpty) if (sourceValidated.listFiles.nonEmpty)
Files.copy(Paths.get(args(0), logFileName), Paths.get(successSourcesName, logFileName)) Files.copy(Paths.get(args(0), logFileName), Paths.get(sourceNameValidated, logFileName))
else else
successSources.delete sourceValidated.delete
if (sourceNotValidated.listFiles.isEmpty) sourceNotValidated.delete
if (sourceError.listFiles.isEmpty) sourceError.delete
if (outputValidated.listFiles.isEmpty) outputValidated.delete
if (outputNotValidated.listFiles.isEmpty) outputNotValidated.delete
if (errorSources.listFiles.isEmpty) errorSources.delete
} match { } match {
case Success(_) => println(s"Converting has been finished. $logFileName located in ${args(0)}") case Success(_) => println(s"Converting has been finished. $logFileName located in ${args(0)}")
case Failure(ex) => println(s"Error. Converting hasn`t been finished: ${ex.getMessage}") case Failure(ex) => println(s"Error. Converting hasn`t been finished: ${ex.toString}")
} }
} else } else
println(s"Error. Converting hasn`t been finished: unable to create source moving directory.") println(s"Error. Converting hasn`t been finished: unable to create directories to move files.")
} }
} }
...@@ -177,12 +212,13 @@ object Main { ...@@ -177,12 +212,13 @@ object Main {
} }
def convert( def convert(
inputStream: InputStream, inputStream: InputStream,
sName: String, sName: String,
oName: String, oName: String,
nsdScheme: XMLValid, nsdScheme: XMLValid,
rtsScheme: XMLValid, rtsScheme: XMLValid,
pp: PrettyPrinter): (Node, String) = { pp: PrettyPrinter): (Node, String) = {
val sourceXml = XML.load(inputStream) val sourceXml = XML.load(inputStream)
val template = Template(sourceXml) val template = Template(sourceXml)
...@@ -199,16 +235,24 @@ object Main { ...@@ -199,16 +235,24 @@ object Main {
sourceXmlValid.loadString(sourceXml.mkString) sourceXmlValid.loadString(sourceXml.mkString)
} match { } match {
case Success(_) => s"'$sName' successfully checked against schema" case Success(_) => s"'$sName' successfully checked against schema"
case Failure(ex) => s"'$sName' isn`t wellformed or invalid: ${ex.getMessage}" case Failure(ex) => s"'$sName' isn`t wellformed or invalid: ${ex.toString}"
} }
val msgCheckOutput = Try { val msgCheckOutput = Try {
outputXmlValid.loadString(outputXml.mkString) outputXmlValid.loadString(outputXml.mkString)
} match { } match {
case Success(_) => s"'$oName' successfully checked against schema" case Success(_) => s"'$oName' successfully checked against schema"
case Failure(ex) => s"'$oName' isn`t wellformed or invalid: ${ex.getMessage}" case Failure(ex) => s"'$oName' isn`t wellformed or invalid: ${ex.toString}"
} }
(outputXml, template.info(s"$msgCheckSource\n$msgCheckOutput") + "\n\n") (outputXml, template.info(s"$msgCheckSource\n$msgCheckOutput") + "\n\n")
} }
case class FileEntry(
name: String,
modified: Long,
streamConvert: Option[InputStream],
streamMove: InputStream,
msg: Option[String]
)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment