Skip to content

Commit 0369c35

Browse files
Better support for the image property
1 parent d9ab0a4 commit 0369c35

9 files changed

Lines changed: 142 additions & 10 deletions

File tree

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>io.frictionlessdata</groupId>
66
<artifactId>datapackage-java</artifactId>
7-
<version>0.6.14-SNAPSHOT</version>
7+
<version>0.6.16-SNAPSHOT</version>
88
<packaging>jar</packaging>
99
<issueManagement>
1010
<url>https://github.com/frictionlessdata/datapackage-java/issues</url>
@@ -22,9 +22,9 @@
2222
<java.version>8</java.version>
2323
<maven.compiler.source>${java.version}</maven.compiler.source>
2424
<maven.compiler.target>${java.version}</maven.compiler.target>
25-
<tableschema-java-version>0.6.15</tableschema-java-version>
25+
<tableschema-java-version>0.6.16</tableschema-java-version>
2626
<hamcrest.version>1.3</hamcrest.version>
27-
<junit.version>5.9.1</junit.version>
27+
<junit.version>5.9.2</junit.version>
2828
<slf4j-simple.version>2.0.5</slf4j-simple.version>
2929
<apache-commons-collections4.version>4.4</apache-commons-collections4.version>
3030
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>

src/main/java/io/frictionlessdata/datapackage/JSONBase.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,24 @@ protected static String getZipFileContentAsString(Path inFilePath, String fileNa
377377
return content;
378378
}
379379

380+
protected static byte[] getZipFileContentAsByteArray(Path inFilePath, String fileName) throws IOException {
381+
// Read in memory the file inside the zip.
382+
ZipFile zipFile = new ZipFile(inFilePath.toFile());
383+
ZipEntry entry = findZipEntry(zipFile, fileName);
384+
385+
// Throw exception if expected datapackage.json file not found.
386+
if(entry == null){
387+
throw new DataPackageException("The zip file does not contain the expected file: " + fileName);
388+
}
389+
try (InputStream inputStream = zipFile.getInputStream(entry);
390+
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
391+
for (int b; (b = inputStream.read()) != -1; ) {
392+
out.write(b);
393+
}
394+
return out.toByteArray();
395+
}
396+
}
397+
380398
public static ObjectNode dereference(File fileObj, Path basePath, boolean isArchivePackage) throws IOException {
381399
String jsonContentString;
382400
if (isArchivePackage) {

src/main/java/io/frictionlessdata/datapackage/Package.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.fasterxml.jackson.annotation.JsonIgnore;
44
import com.fasterxml.jackson.annotation.JsonInclude;
55
import com.fasterxml.jackson.annotation.JsonInclude.Include;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
67
import com.fasterxml.jackson.core.type.TypeReference;
78
import com.fasterxml.jackson.databind.JsonNode;
89
import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -286,18 +287,36 @@ public URL getHomepage() {
286287
*
287288
* @return path or URL to the image data
288289
*/
290+
@JsonProperty("image")
289291
public String getImagePath() {
290292
return image;
291293
}
292294

293295
/**
294296
* Returns the image data if the image is stored inside the data package, null if {@link #getImagePath()}
295-
* would return a URLL
297+
* would return a URL
296298
*
297299
* @return binary image data
298300
*/
299-
public byte[] getImage() {
300-
return imageData;
301+
@JsonIgnore
302+
public byte[] getImage() throws IOException {
303+
if (null != imageData)
304+
return imageData;
305+
if (!StringUtils.isEmpty(image)) {
306+
if (isArchivePackage) {
307+
return getZipFileContentAsByteArray((Path)basePath, image);
308+
} else {
309+
File imgFile = new File (((Path)basePath).toFile(), image);
310+
try (InputStream inputStream = new FileInputStream(imgFile);
311+
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
312+
for (int b; (b = inputStream.read()) != -1; ) {
313+
out.write(b);
314+
}
315+
return out.toByteArray();
316+
}
317+
}
318+
}
319+
return null;
301320
}
302321

303322
public ZonedDateTime getCreated() {
@@ -382,6 +401,7 @@ public Object getProperty(String key, Class<?> clazz) {
382401
* an invalid Package would throw an exception.
383402
* @return true if either `strictValidation` is true or no errors were encountered
384403
*/
404+
@JsonIgnore
385405
public boolean isValid() {
386406
if (strictValidation){
387407
return true;
@@ -837,7 +857,8 @@ private void setImagePath(String image) {
837857
}
838858

839859
public void setImage(String fileName, byte[]data) throws IOException {
840-
this.image = fileName;
860+
String sanitizedFileName = fileName.replaceAll("[\\s/\\\\]+", "_");
861+
this.image = sanitizedFileName;
841862
this.imageData = data;
842863
}
843864

@@ -962,7 +983,6 @@ private void writeDescriptor (FileSystem outFs, String parentDirName) throws IOE
962983
Path nf = outFs.getPath(parentDirName+File.separator+DATAPACKAGE_FILENAME);
963984
try (Writer writer = Files.newBufferedWriter(nf, StandardCharsets.UTF_8, StandardOpenOption.CREATE)) {
964985
ObjectNode jsonNode = this.getJsonNode();
965-
jsonNode.remove(JSON_KEY_IMAGE);
966986
writer.write(jsonNode.toPrettyString());
967987
}
968988
}

src/test/java/io/frictionlessdata/datapackage/PackageTest.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import io.frictionlessdata.tableschema.schema.Schema;
1313
import io.frictionlessdata.tableschema.tabledatasource.TableDataSource;
1414
import io.frictionlessdata.tableschema.util.JsonUtil;
15-
import org.junit.Assert;
1615
import org.junit.jupiter.api.Assertions;
1716
import org.junit.jupiter.api.BeforeAll;
1817
import org.junit.jupiter.api.DisplayName;
@@ -445,6 +444,46 @@ public void testSetProfile() throws Exception {
445444
Assertions.assertEquals(Profile.PROFILE_DATA_PACKAGE_DEFAULT, dp.getProfile());
446445
}
447446

447+
@Test
448+
@DisplayName("Test setting the 'image' propertye")
449+
public void testSetImage() throws Exception {
450+
Path tempDirPath = Files.createTempDirectory("datapackage-");
451+
String fName = "/fixtures/datapackages/with-image";
452+
Path resourcePath = TestUtil.getResourcePath(fName);
453+
Package dp = new Package(resourcePath, true);
454+
455+
byte[] imageData = TestUtil.getResourceContent("/fixtures/files/test.png");
456+
dp.setImage("test.png", imageData);
457+
458+
File tmpFile = new File(tempDirPath.toFile(), "saved-pkg.zip");
459+
dp.write(tmpFile, true);
460+
461+
// Read the datapckage we just saved in the temp dir.
462+
Package readPackage = new Package(tmpFile.toPath(), false);
463+
byte[] readImageData = readPackage.getImage();
464+
Assertions.assertArrayEquals(imageData, readImageData);
465+
}
466+
467+
@Test
468+
@DisplayName("Test setting the 'image' property, ZIP file")
469+
public void testSetImageZip() throws Exception {
470+
Path tempDirPath = Files.createTempDirectory("datapackage-");
471+
String fName = "/fixtures/datapackages/employees/datapackage.json";
472+
Path resourcePath = TestUtil.getResourcePath(fName);
473+
Package dp = new Package(resourcePath, true);
474+
475+
byte[] imageData = TestUtil.getResourceContent("/fixtures/files/test.png");
476+
dp.setImage("test.png", imageData);
477+
478+
File tmpFile = new File(tempDirPath.toFile(), "saved-pkg.zip");
479+
dp.write(tmpFile, true);
480+
481+
// Read the datapckage we just saved in the zip file.
482+
Package readPackage = new Package(tmpFile.toPath(), false);
483+
byte[] readImageData = readPackage.getImage();
484+
Assertions.assertArrayEquals(imageData, readImageData);
485+
}
486+
448487
@Test
449488
@DisplayName("Test setting invalid 'profile' property, must throw")
450489
public void testSetInvalidProfile() throws Exception {
@@ -633,7 +672,7 @@ public void testWriteImageToFolderPackage() throws Exception{
633672
System.out.println(tempDirPath);
634673
File descriptor = new File (dir, "datapackage.json");
635674
String json = String.join("\n", Files.readAllLines(descriptor.toPath()));
636-
Assertions.assertFalse(json.contains("\"image\""));
675+
Assertions.assertFalse(json.contains("\"imageData\""));
637676
}
638677

639678
@Test
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
id,name,dateOfBirth,isAdmin,addressCoordinates,contractLength,info
2+
1,John Doe,1976-01-13,true,"{""lon"": 90, ""lat"": 45}",P2DT3H4M,"{""ssn"": 90, ""pin"": 45, ""rate"": 83.23}"
3+
2,Frank McKrank,1992-02-14,false,"{""lon"": 90, ""lat"": 45}",PT15M,"{""ssn"": 90, ""pin"": 45, ""rate"": 83.23}"
4+
3,Pencil Vester,1983-03-16,false,"{""lon"": 90, ""lat"": 45}",PT20.345S,"{""ssn"": 90, ""pin"": 45, ""rate"": 83.23}"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "employees",
3+
"profile": "tabular-data-package",
4+
"image" : "test.png",
5+
"resources": [{
6+
"name": "employee-data",
7+
"path": "data/employees.csv",
8+
"schema": "schema.json",
9+
"profile": "tabular-data-resource"
10+
}
11+
]
12+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"fields":[
3+
{
4+
"name":"id",
5+
"format":"default",
6+
"type":"integer"
7+
},
8+
{
9+
"name":"name",
10+
"format":"default",
11+
"type":"string"
12+
},
13+
{
14+
"name":"dateOfBirth",
15+
"format":"default",
16+
"type":"date"
17+
},
18+
{
19+
"name":"isAdmin",
20+
"format":"default",
21+
"type":"boolean"
22+
},
23+
{
24+
"name":"addressCoordinates",
25+
"format":"object",
26+
"type":"geopoint"
27+
},
28+
{
29+
"name":"contractLength",
30+
"format":"default",
31+
"type":"duration"
32+
},
33+
{
34+
"name":"info",
35+
"format":"default",
36+
"type":"object"
37+
}
38+
]
39+
}
2.15 KB
Loading
2.15 KB
Loading

0 commit comments

Comments
 (0)