Skip to content

Commit 06713e0

Browse files
committed
Added linux support
1 parent 7845963 commit 06713e0

File tree

8 files changed

+226
-42
lines changed

8 files changed

+226
-42
lines changed

.vscode/launch.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
// Use IntelliSense to find out which attributes exist for C# debugging
3+
// Use hover for the description of the existing attributes
4+
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": ".NET Core Launch (console)",
9+
"type": "coreclr",
10+
"request": "launch",
11+
"preLaunchTask": "build",
12+
// If you have changed target frameworks, make sure to update the program path.
13+
"program": "${workspaceFolder}/PDfAValidatorTest/bin/Debug/netcoreapp2.1/PDfAValidatorTest.dll",
14+
"args": [],
15+
"cwd": "${workspaceFolder}/PDfAValidatorTest",
16+
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
17+
"console": "internalConsole",
18+
"stopAtEntry": false
19+
},
20+
{
21+
"name": ".NET Core Attach",
22+
"type": "coreclr",
23+
"request": "attach",
24+
"processId": "${command:pickProcess}"
25+
}
26+
]
27+
}

.vscode/tasks.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "build",
6+
"command": "dotnet",
7+
"type": "process",
8+
"args": [
9+
"build",
10+
"${workspaceFolder}/PDfAValidatorTest/PDfAValidatorTest.csproj"
11+
],
12+
"problemMatcher": "$tsc"
13+
},
14+
{
15+
"label": "publish",
16+
"command": "dotnet",
17+
"type": "process",
18+
"args": [
19+
"publish",
20+
"${workspaceFolder}/PDfAValidatorTest/PDfAValidatorTest.csproj"
21+
],
22+
"problemMatcher": "$tsc"
23+
},
24+
{
25+
"label": "watch",
26+
"command": "dotnet",
27+
"type": "process",
28+
"args": [
29+
"watch",
30+
"run",
31+
"${workspaceFolder}/PDfAValidatorTest/PDfAValidatorTest.csproj"
32+
],
33+
"problemMatcher": "$tsc"
34+
}
35+
]
36+
}

PDfAValidatorTest/PdfAValidatorTest.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,42 @@
1+
using System.IO;
2+
using System.Linq;
3+
using System.Runtime.InteropServices;
14
using Xunit;
25

36
namespace PDfAValidatorTest
47
{
58
public class PdfAValidatorTest
69
{
10+
[Fact]
11+
public void ShouldUnpackNewDirectoryInTempdirectory()
12+
{
13+
var listOfDirectoriesInTempWithoutVeraPdf = Directory.GetDirectories(Path.GetTempPath());
14+
using (var pdfAValidator = new PdfAValidator.PdfAValidator())
15+
{
16+
var listOfDirectoriesInTempWithVeraPdf = Directory.GetDirectories(Path.GetTempPath());
17+
var newDirectories = listOfDirectoriesInTempWithVeraPdf.Except(listOfDirectoriesInTempWithoutVeraPdf);
18+
19+
Assert.Equal(1, newDirectories.Count());
20+
var scriptPath = pdfAValidator.VeraPdfStarterScript;
21+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
22+
Assert.Equal(".bat", scriptPath.Substring(scriptPath.Length - 4));
23+
24+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
25+
Assert.Equal("verapdf", scriptPath.Substring(scriptPath.Length - 7));
26+
27+
Assert.True(File.Exists(scriptPath), scriptPath + " does not exist.");
28+
}
29+
var listOfDirectoriesInTempAfterVeraPdf = Directory.GetDirectories(Path.GetTempPath());
30+
Assert.Equal(listOfDirectoriesInTempAfterVeraPdf.Length, listOfDirectoriesInTempWithoutVeraPdf.Length);
31+
32+
}
33+
734
[Fact]
835
public void ShouldDetectCompliantPdfA()
936
{
1037
using (var pdfAValidator = new PdfAValidator.PdfAValidator())
1138
{
39+
Assert.True(File.Exists(@"./TestPdfFiles/FromLibreOffice.pdf"));
1240
var result = pdfAValidator.Validate(@"./TestPdfFiles/FromLibreOffice.pdf");
1341
Assert.True(result);
1442
}
@@ -19,6 +47,7 @@ public void ShouldGetDetailedReportFromPdfA()
1947
{
2048
using (var pdfAValidator = new PdfAValidator.PdfAValidator())
2149
{
50+
Assert.True(File.Exists(@"./TestPdfFiles/FromLibreOffice.pdf"));
2251
var result = pdfAValidator.ValidateWithDetailedReport(@"./TestPdfFiles/FromLibreOffice.pdf");
2352
Assert.True(result.jobs.job.validationReport.isCompliant);
2453
Assert.True(result.jobs.job.validationReport.profileName == "PDF/A-1A validation profile");
@@ -30,6 +59,7 @@ public void ShouldDetectNonCompliantPdfA()
3059
{
3160
using (var pdfAValidator = new PdfAValidator.PdfAValidator())
3261
{
62+
Assert.True(File.Exists(@"./TestPdfFiles/FromLibreOfficeNonPdfA.pdf"));
3363
var result = pdfAValidator.Validate(@"./TestPdfFiles/FromLibreOfficeNonPdfA.pdf");
3464
Assert.False(result);
3565
}
@@ -40,6 +70,7 @@ public void ShouldGetDetailedReportFromNonCompliantPdfA()
4070
{
4171
using (var pdfAValidator = new PdfAValidator.PdfAValidator())
4272
{
73+
Assert.True(File.Exists(@"./TestPdfFiles/FromLibreOfficeNonPdfA.pdf"));
4374
var result = pdfAValidator.ValidateWithDetailedReport(@"./TestPdfFiles/FromLibreOfficeNonPdfA.pdf");
4475
Assert.False(result.jobs.job.validationReport.isCompliant);
4576
Assert.True(result.jobs.job.validationReport.profileName == "PDF/A-1B validation profile");

PdfAValidator/PdfAValidator.cs

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
using System.IO;
44
using System.IO.Compression;
55
using System.Reflection;
6+
using System.Runtime.InteropServices;
7+
using System.Threading.Tasks;
68
using System.Xml.Serialization;
79

810
// TODOS:
911
// Performance - now every call causes verapdf to be unpacked
10-
// Inportability - Make verapdf working on linux
1112
// Codestyle - make this code great again
1213
// Fix the generated casing in report.cs
1314

@@ -17,7 +18,7 @@ public class PdfAValidator : IDisposable
1718
{
1819
public void Dispose()
1920
{
20-
Directory.Delete(_pathVeraPdf, true);
21+
Directory.Delete(_pathVeraPdfDirectory, true);
2122
}
2223

2324
/// <summary>
@@ -26,8 +27,9 @@ public void Dispose()
2627
/// <param name="pathToVeraPdfBin"></param>
2728
public PdfAValidator(string pathToVeraPdfBin, string pathToJava)
2829
{
29-
_pathVeraPdfBat = pathToVeraPdfBin;
30-
_pathJava = pathToJava;
30+
// TODO Test
31+
VeraPdfStarterScript = pathToVeraPdfBin;
32+
PathJava = pathToJava;
3133
}
3234

3335
/// <summary>
@@ -36,10 +38,10 @@ public PdfAValidator(string pathToVeraPdfBin, string pathToJava)
3638
public PdfAValidator()
3739
{ intiPathToVeraPdfBinAndJava(); }
3840

39-
private string _pathVeraPdf;
40-
private string _pathJava;
41+
private string _pathVeraPdfDirectory;
42+
public string PathJava { private set; get; }
4143
private string _pathZipVeraPdf;
42-
private string _pathVeraPdfBat;
44+
public string VeraPdfStarterScript { private set; get; }
4345

4446
public bool Validate(string pathToPdfFile)
4547
{
@@ -59,52 +61,110 @@ public report ValidateWithDetailedReport(string pathToPdfFile)
5961
{
6062
string concatedVeraPdfOutput = string.Empty;
6163

62-
process.StartInfo.FileName = _pathVeraPdfBat;
64+
process.StartInfo.FileName = VeraPdfStarterScript;
6365
process.StartInfo.RedirectStandardOutput = true;
64-
process.StartInfo.RedirectStandardError = false;
66+
process.StartInfo.RedirectStandardError = true;
6567
process.StartInfo.UseShellExecute = false;
6668
process.StartInfo.CreateNoWindow = true;
67-
process.StartInfo.EnvironmentVariables["JAVACMD"] = _pathJava;
69+
if (!String.IsNullOrEmpty(PathJava))
70+
process.StartInfo.EnvironmentVariables["JAVACMD"] = PathJava;
6871
ProcessStartInfo startInfo = process.StartInfo;
6972
string[] arguments = new string[] { "\"", pathToPdfFile, "\" " };
7073
startInfo.Arguments = string.Concat(arguments);
7174
process.Start();
7275

73-
while (true)
76+
var outputResult = GetStreamOutput(process.StandardOutput);
77+
var errorResult = GetStreamOutput(process.StandardError);
78+
79+
process.WaitForExit();
80+
81+
if (string.IsNullOrEmpty(errorResult))
7482
{
75-
string standardOutputLine = process.StandardOutput.ReadLine();
76-
if (standardOutputLine == null)
77-
{
78-
using (var sr = new StringReader(concatedVeraPdfOutput))
79-
{
80-
var veraPdfReport = (report)new XmlSerializer(typeof(report)).Deserialize(sr);
81-
return veraPdfReport;
82-
}
83-
}
84-
85-
concatedVeraPdfOutput += standardOutputLine;
83+
var veraPdfReport = DeserializeXml<report>(outputResult);
84+
return veraPdfReport;
8685
}
86+
87+
throw new VeraPdfException("Calling VearPdf caused an error: " + errorResult);
8788
}
8889
}
8990

91+
private string GetStreamOutput(StreamReader stream)
92+
{
93+
//Read output in separate task to avoid deadlocks
94+
var outputReadTask = Task.Run(() => stream.ReadToEnd());
95+
96+
return outputReadTask.Result;
97+
}
98+
99+
static T DeserializeXml<T>(string sourceXML) where T : class
100+
{
101+
var serializer = new XmlSerializer(typeof(T));
102+
T result = null;
103+
104+
using (TextReader reader = new StringReader(sourceXML))
105+
result = (T)serializer.Deserialize(reader);
106+
return result;
107+
}
108+
109+
public void SetLinuxFileExecuteable(string filePath)
110+
{
111+
var chmodCmd = "chmod 700 " + filePath;
112+
var escapedArgs = chmodCmd.Replace("\"", "\\\"");
113+
114+
var process = new Process
115+
{
116+
StartInfo = new ProcessStartInfo
117+
{
118+
RedirectStandardOutput = true,
119+
UseShellExecute = false,
120+
CreateNoWindow = true,
121+
WindowStyle = ProcessWindowStyle.Hidden,
122+
FileName = "/bin/bash",
123+
Arguments = $"-c \"{escapedArgs}\""
124+
}
125+
};
126+
process.Start();
127+
process.WaitForExit();
128+
}
129+
90130
private void intiPathToVeraPdfBinAndJava()
91131
{
92-
_pathVeraPdf = Path.Combine(Path.GetTempPath(), "VeraPdf" + Guid.NewGuid());
93-
Directory.CreateDirectory(_pathVeraPdf);
94-
_pathZipVeraPdf = Path.Combine(_pathVeraPdf, "VeraPdf.zip");
132+
_pathVeraPdfDirectory = Path.Combine(Path.GetTempPath(), "VeraPdf" + Guid.NewGuid());
133+
Directory.CreateDirectory(_pathVeraPdfDirectory);
134+
_pathZipVeraPdf = Path.Combine(_pathVeraPdfDirectory, "VeraPdf.zip");
95135

96136
var assembly = Assembly.GetExecutingAssembly();
97-
using (var stream = assembly.GetManifestResourceStream("PdfAValidator.VeraPdf.zip"))
98-
using (var fileStream = File.Create(_pathZipVeraPdf))
137+
138+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
99139
{
100-
stream.Seek(0, SeekOrigin.Begin);
101-
stream.CopyTo(fileStream);
140+
using (var stream = assembly.GetManifestResourceStream("PdfAValidator.VeraPdf.Windows.zip"))
141+
using (var fileStream = File.Create(_pathZipVeraPdf))
142+
{
143+
stream.Seek(0, SeekOrigin.Begin);
144+
stream.CopyTo(fileStream);
145+
}
146+
ZipFile.ExtractToDirectory(_pathZipVeraPdf, _pathVeraPdfDirectory);
147+
VeraPdfStarterScript = Path.Combine(_pathVeraPdfDirectory, "verapdf", "verapdf.bat");
148+
// took from https://adoptopenjdk.net/releases.html?variant=openjdk8&jvmVariant=hotspot#x64_win
149+
PathJava = Path.Combine(_pathVeraPdfDirectory, "verapdf", "jdk8u202-b08-jre", "bin", "java");
102150
}
151+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
152+
{
153+
var names = assembly.GetManifestResourceNames();
154+
155+
using (var stream = assembly.GetManifestResourceStream("PdfAValidator.VeraPdf.Linux.zip"))
156+
using (var fileStream = File.Create(_pathZipVeraPdf))
157+
{
158+
stream.Seek(0, SeekOrigin.Begin);
159+
stream.CopyTo(fileStream);
160+
}
161+
ZipFile.ExtractToDirectory(_pathZipVeraPdf, _pathVeraPdfDirectory);
103162

104-
ZipFile.ExtractToDirectory(_pathZipVeraPdf, _pathVeraPdf);
105-
_pathVeraPdfBat = Path.Combine(_pathVeraPdf, "VeraPdf", "verapdf.bat");
106-
// took from https://adoptopenjdk.net/releases.html?variant=openjdk8&jvmVariant=hotspot#x64_win
107-
_pathJava = Path.Combine(_pathVeraPdf, "VeraPdf", "jdk8u202-b08-jre", "bin", "java");
163+
VeraPdfStarterScript = Path.Combine(_pathVeraPdfDirectory, "verapdf", "verapdf");
164+
SetLinuxFileExecuteable(VeraPdfStarterScript);
165+
}
166+
else
167+
throw new NotImplementedException("Sorry, only supporting linux and windows.");
108168
}
109169
}
110170
}

PdfAValidator/PdfAValidator.csproj

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,40 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
32
<PropertyGroup>
43
<TargetFramework>netcoreapp2.1</TargetFramework>
54
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
65
<RepositoryUrl>https://github.com/Codeuctivity/PdfAValidatorApi</RepositoryUrl>
76
<PackageTags>Pdf PdfA VeraPdf Pdf/A</PackageTags>
8-
<PackageLicenseUrl>https://github.com/Codeuctivity/PdfAValidatorApi/blob/master/LICENSE</PackageLicenseUrl>
7+
<License>AGPL</License>
98
<Authors>Stefan Seeland</Authors>
109
<Company>Codeuctivity</Company>
11-
<AssemblyVersion>1.0.0.16</AssemblyVersion>
12-
<FileVersion>1.0.0.15</FileVersion>
13-
<Version>1.0.16</Version>
10+
<AssemblyVersion>1.0.0.17</AssemblyVersion>
11+
<FileVersion>1.0.0.17</FileVersion>
12+
<Version>1.0.17</Version>
1413
<PackageIconUrl>https://avatars3.githubusercontent.com/u/8453155?v=2&amp;s=200</PackageIconUrl>
1514
<PackageProjectUrl>https://github.com/Codeuctivity/PdfAValidatorApi</PackageProjectUrl>
1615
<Description>PdfAValidator is based on VeraPdf and is an open source conformance checker for PDF/A files. It is designed to help archives and libraries check that their PDF/A collections conform to the appropriate ISO 19005 archiving standard specification.</Description>
1716
</PropertyGroup>
1817

1918
<ItemGroup>
20-
<None Remove="VeraPdf.zip" />
19+
<None Remove="VeraPdf.Windows.zip" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<EmbeddedResource Include="VeraPdf.Windows.zip" />
24+
</ItemGroup>
25+
26+
<ItemGroup>
27+
<None Remove="VeraPdf.Linux.zip" />
2128
</ItemGroup>
2229

2330
<ItemGroup>
24-
<EmbeddedResource Include="VeraPdf.zip" />
31+
<EmbeddedResource Include="VeraPdf.Linux.zip" />
2532
</ItemGroup>
2633

27-
2834
<ItemGroup>
2935
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
3036
</ItemGroup>
3137

32-
3338
<ItemGroup>
3439
<Folder Include="Properties\" />
3540
</ItemGroup>

PdfAValidator/VeraPdf.Linux.zip

6.09 MB
Binary file not shown.
File renamed without changes.

PdfAValidator/VeraPdfException.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Runtime.Serialization;
3+
4+
namespace PdfAValidator
5+
{
6+
[Serializable]
7+
internal class VeraPdfException : Exception
8+
{
9+
public VeraPdfException()
10+
{
11+
}
12+
13+
public VeraPdfException(string message) : base(message)
14+
{
15+
}
16+
17+
public VeraPdfException(string message, Exception innerException) : base(message, innerException)
18+
{
19+
}
20+
21+
protected VeraPdfException(SerializationInfo info, StreamingContext context) : base(info, context)
22+
{
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)