Skip to content

Commit a382c66

Browse files
authored
[fj-doc-val-core] DocValidatorTypeCheck facade to check file type #260 (#261)
[fj-doc-val-p7m] check the inner type on P7MContentValidator
1 parent 068f5fa commit a382c66

File tree

6 files changed

+201
-28
lines changed

6 files changed

+201
-28
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- [fj-doc-val-core] DocValidatorTypeCheck facade to check file type
13+
- [fj-doc-val-p7m] check the inner type on P7MContentValidator
14+
1015
### Changed
1116

1217
- [fj-doc-playground-quarkus] show quakus version
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.fugerit.java.doc.val.core;
2+
3+
import lombok.Getter;
4+
import org.fugerit.java.core.function.SafeFunction;
5+
import org.fugerit.java.core.io.StreamIO;
6+
7+
import java.io.ByteArrayInputStream;
8+
import java.io.InputStream;
9+
10+
/**
11+
* This facade tries to retrieve a document's type.
12+
*
13+
*/
14+
public class DocValidatorTypeCheck {
15+
16+
@Getter
17+
private DocValidatorFacade facade;
18+
19+
private DocValidatorTypeCheck( DocValidatorFacade facade ) {
20+
this.facade = facade;
21+
}
22+
23+
/**
24+
* Type check of a byte stream against the configured DocTypeValidator facade.
25+
*
26+
* It will return <code>null</code> if the stream is not valid for all the validators, otherwise DocTypeValidator.getMimeType() of the first validator matching the type.
27+
*
28+
* NOTE: This method always buffer the input, so it can be memory consuming.
29+
*
30+
* @param is the byte stream to check
31+
* @return <code>null</code> if the stream is not valid for all the validators, otherwise DocTypeValidator.getMimeType() of the first validator matching the type
32+
*/
33+
public String checkType(InputStream is) {
34+
return SafeFunction.get( () -> this.checkType( StreamIO.readBytes( is ) ) );
35+
}
36+
37+
/**
38+
* Type check for an input document against the configured DocTypeValidator facade.
39+
*
40+
* It will return <code>null</code> if the stream is not valid for all the validators, otherwise DocTypeValidator.getMimeType() of the first validator matching the type.
41+
*
42+
* NOTE: This method always buffer the input, so it can be memory consuming.
43+
*
44+
* @param buffer the document to check
45+
* @return <code>null</code> if the input is not valid for all the validators, otherwise DocTypeValidator.getMimeType() of the first validator matching the type
46+
*/
47+
public String checkType(byte[] buffer) {
48+
return SafeFunction.get( () -> {
49+
for ( DocTypeValidator validator : this.facade.validators() ) {
50+
try (ByteArrayInputStream input = new ByteArrayInputStream( buffer )) {
51+
if ( validator.check( input ) ) {
52+
return validator.getMimeType();
53+
}
54+
}
55+
}
56+
// default case, type not found
57+
return null;
58+
} );
59+
}
60+
61+
public static DocValidatorTypeCheck newInstance( DocTypeValidator... validator ) {
62+
return newInstance( DocValidatorFacade.newFacadeStrict( validator ) );
63+
}
64+
65+
public static DocValidatorTypeCheck newInstance( DocValidatorFacade facade ) {
66+
return new DocValidatorTypeCheck( facade );
67+
}
68+
69+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package test.org.fugerit.java.doc.core.val;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.fugerit.java.core.function.SafeFunction;
5+
import org.fugerit.java.core.lang.helpers.ClassHelper;
6+
import org.fugerit.java.doc.val.core.DocValidatorTypeCheck;
7+
import org.fugerit.java.doc.val.core.basic.ImageValidator;
8+
import org.junit.Assert;
9+
import org.junit.Test;
10+
11+
import java.awt.*;
12+
import java.io.InputStream;
13+
14+
@Slf4j
15+
public class TestDocValidatorTypeCheck {
16+
17+
private static final DocValidatorTypeCheck TYPE_CHECK = DocValidatorTypeCheck.newInstance(
18+
ImageValidator.JPG_VALIDATOR, ImageValidator.PNG_VALIDATOR );
19+
20+
private static final String BASE_PATH = "sample";
21+
22+
private String worker( String fileName ) {
23+
return SafeFunction.get( () -> {
24+
String path = BASE_PATH+"/"+fileName;
25+
log.info( "test path {}", path );
26+
try ( InputStream is = ClassHelper.loadFromDefaultClassLoader( path ) ) {
27+
return TYPE_CHECK.checkType( is );
28+
}
29+
} );
30+
}
31+
32+
@Test
33+
public void testJpg() {
34+
Assert.assertEquals(ImageValidator.JPG_VALIDATOR.getMimeType(), this.worker( "jpg_as_jpg.jpg" ) );
35+
}
36+
37+
@Test
38+
public void testPng() {
39+
Assert.assertEquals(ImageValidator.PNG_VALIDATOR.getMimeType(), this.worker( "png_as_png.png" ) );
40+
}
41+
42+
@Test
43+
public void testNull() {
44+
Assert.assertNull( this.worker( "pdf_as_jpg.jpg" ) );
45+
}
46+
47+
}
Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
package org.fugerit.java.doc.val.p7m;
22

3-
import java.io.ByteArrayInputStream;
43
import java.io.ByteArrayOutputStream;
54
import java.io.InputStream;
65

76
import org.fugerit.java.core.cfg.ConfigRuntimeException;
7+
import org.fugerit.java.core.function.SafeFunction;
88
import org.fugerit.java.doc.val.core.DocTypeValidationResult;
9-
import org.fugerit.java.doc.val.core.DocTypeValidator;
109
import org.fugerit.java.doc.val.core.DocValidatorFacade;
10+
import org.fugerit.java.doc.val.core.DocValidatorTypeCheck;
1111
import org.fugerit.java.doc.val.core.basic.AbstractDocTypeValidator;
1212

1313
import lombok.Getter;
1414
import lombok.Setter;
1515

1616
public class P7MContentValidator extends AbstractDocTypeValidator {
17+
18+
public static final boolean DEFAULT_PROCEED_ON_INNTER_CHECK = Boolean.FALSE;
19+
20+
@Getter @Setter private DocValidatorTypeCheck facade;
21+
22+
@Getter private boolean proceedOnInnerTypeCheck;
1723

18-
@Getter @Setter private DocValidatorFacade facade;
19-
20-
public P7MContentValidator(DocValidatorFacade facade) {
24+
public P7MContentValidator(DocValidatorFacade facade, boolean proceedOnInnerTypeCheck) {
2125
super( P7MValidator.MIME_TYPE, P7MValidator.EXTENSION );
22-
this.facade = facade;
26+
this.facade = DocValidatorTypeCheck.newInstance( facade );
27+
this.proceedOnInnerTypeCheck = proceedOnInnerTypeCheck;
28+
}
29+
30+
public P7MContentValidator(DocValidatorFacade facade) {
31+
this( facade, DEFAULT_PROCEED_ON_INNTER_CHECK );
2332
}
2433

2534
public P7MContentValidator() {
@@ -28,34 +37,43 @@ public P7MContentValidator() {
2837

2938
@Override
3039
public DocTypeValidationResult validate(InputStream is) {
31-
return this.validationHelper( () -> {
40+
return this.validationHelper( () -> this.checkInnerType( is ) );
41+
}
42+
43+
public String checkInnerType(InputStream is ) {
44+
return SafeFunction.get( () -> {
3245
try ( ByteArrayOutputStream os = new ByteArrayOutputStream() ) {
3346
P7MUtils.extractContent(is, os);
34-
if ( this.getFacade() != null ) {
35-
boolean isValid = false;
36-
for ( DocTypeValidator validator : this.getFacade().validators() ) {
37-
try ( ByteArrayInputStream bis = new ByteArrayInputStream( os.toByteArray() ) ) {
38-
if ( validator.check( bis ) ) {
39-
isValid = true;
40-
break;
41-
}
42-
}
43-
}
44-
if ( !isValid ) {
47+
if ( this.facade.getFacade() != null ) {
48+
String mimeType = this.facade.checkType( os.toByteArray() );
49+
if ( mimeType != null || this.proceedOnInnerTypeCheck ) {
50+
return mimeType;
51+
} else {
4552
throw new ConfigRuntimeException( "Content not valid for this validator facade!" );
4653
}
54+
} else {
55+
return null;
4756
}
4857
}
4958
} );
5059
}
5160

5261
public P7MContentValidator withDocValidatorFacade( DocValidatorFacade facade ) {
53-
this.setFacade( facade );
62+
this.setFacade( DocValidatorTypeCheck.newInstance( facade ) );
5463
return this;
5564
}
56-
65+
66+
public P7MContentValidator withProceedOnInnerTypeCheck( boolean proceedOnInnerTypeCheck ) {
67+
this.proceedOnInnerTypeCheck = proceedOnInnerTypeCheck;
68+
return this;
69+
}
70+
5771
public static P7MContentValidator newValidator( DocValidatorFacade facade ) {
58-
return new P7MContentValidator().withDocValidatorFacade(facade);
72+
return newValidator( facade, DEFAULT_PROCEED_ON_INNTER_CHECK );
73+
}
74+
75+
public static P7MContentValidator newValidator( DocValidatorFacade facade, boolean proceedOnInnerTypeCheck ) {
76+
return new P7MContentValidator().withDocValidatorFacade(facade).withProceedOnInnerTypeCheck( proceedOnInnerTypeCheck );
5977
}
6078

6179
}

fj-doc-val-p7m/src/test/java/test/org/fugerit/java/doc/val/p7m/TestDocValidatorFacade.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@
22

33
import java.io.InputStream;
44

5+
import lombok.extern.slf4j.Slf4j;
56
import org.fugerit.java.core.function.SafeFunction;
67
import org.fugerit.java.core.lang.helpers.ClassHelper;
78
import org.fugerit.java.doc.val.core.DocValidatorFacade;
89
import org.junit.Assert;
910
import org.slf4j.Logger;
1011
import org.slf4j.LoggerFactory;
1112

13+
@Slf4j
1214
public class TestDocValidatorFacade {
1315

14-
private static final Logger logger = LoggerFactory.getLogger( TestDocValidatorFacade.class );
15-
16-
private static final String BASE_PATH = "sample";
16+
protected static final String BASE_PATH = "sample";
1717

1818
protected boolean worker( DocValidatorFacade facade, String fileName, boolean result ) {
1919
return SafeFunction.get( () -> {
2020
String path = BASE_PATH+"/"+fileName;
21-
logger.info( "test path {}, expected result {}", path, result );
21+
log.info( "test path {}, expected result {}", path, result );
2222
try ( InputStream is = ClassHelper.loadFromDefaultClassLoader( path ) ) {
2323
boolean check = facade.check(fileName, is);
2424
Assert.assertEquals( "File check failed", result, check );

fj-doc-val-p7m/src/test/java/test/org/fugerit/java/doc/val/p7m/TestP7MContentValidator.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
package test.org.fugerit.java.doc.val.p7m;
22

3+
import lombok.extern.slf4j.Slf4j;
4+
import org.fugerit.java.core.function.SafeFunction;
5+
import org.fugerit.java.core.lang.helpers.ClassHelper;
36
import org.fugerit.java.doc.val.core.DocValidatorFacade;
47
import org.fugerit.java.doc.val.core.basic.ImageValidator;
58
import org.fugerit.java.doc.val.p7m.P7MContentValidator;
69
import org.fugerit.java.doc.val.pdf.box.PdfboxStrictValidator;
710
import org.junit.Assert;
811
import org.junit.Test;
912

13+
import java.io.InputStream;
14+
15+
@Slf4j
1016
public class TestP7MContentValidator extends TestDocValidatorFacade {
1117

18+
private static final String FILENAME_PDF_AS_P7M = "pdf_as_pdf.p7m";
19+
1220
private static final DocValidatorFacade FACADE_PDF = DocValidatorFacade.newFacadeStrict(
1321
P7MContentValidator.newValidator( DocValidatorFacade.newFacade( PdfboxStrictValidator.DEFAULT ) )
1422
);
@@ -20,23 +28,49 @@ public class TestP7MContentValidator extends TestDocValidatorFacade {
2028
private static final DocValidatorFacade FACADE_NULL = DocValidatorFacade.newFacadeStrict(
2129
P7MContentValidator.newValidator( null )
2230
);
31+
32+
private static final P7MContentValidator CONTENT_JPG_PROCEED =
33+
P7MContentValidator.newValidator( DocValidatorFacade.newFacade( ImageValidator.JPG_VALIDATOR ), true );
34+
35+
private static final P7MContentValidator CONTENT_PDF_PROCEED =
36+
P7MContentValidator.newValidator( DocValidatorFacade.newFacade( PdfboxStrictValidator.DEFAULT ), true );
37+
38+
protected String worker( P7MContentValidator validator, String fileName ) {
39+
return SafeFunction.get( () -> {
40+
String path = BASE_PATH+"/"+fileName;
41+
log.info( "test path to check {}", path );
42+
try ( InputStream is = ClassHelper.loadFromDefaultClassLoader( path ) ) {
43+
return validator.checkInnerType( is );
44+
}
45+
} );
46+
}
2347

2448
@Test
2549
public void testP7MAsP7M() {
26-
boolean ok = this.worker(FACADE_PDF, "pdf_as_pdf.p7m", true );
50+
boolean ok = this.worker(FACADE_PDF, FILENAME_PDF_AS_P7M, true );
2751
Assert.assertTrue( ok );
2852
}
2953

3054
@Test
3155
public void testP7MAsP7MNull() {
32-
boolean ok = this.worker(FACADE_NULL, "pdf_as_pdf.p7m", true );
56+
boolean ok = this.worker(FACADE_NULL, FILENAME_PDF_AS_P7M, true );
3357
Assert.assertTrue( ok );
3458
}
3559

3660
@Test
3761
public void testP7MAsP7MKo() {
38-
boolean ok = this.worker(FACADE_JPG, "pdf_as_pdf.p7m", false );
62+
boolean ok = this.worker(FACADE_JPG, FILENAME_PDF_AS_P7M, false );
3963
Assert.assertTrue( ok );
4064
}
65+
66+
@Test
67+
public void testProccedKo() {
68+
Assert.assertNull( this.worker( CONTENT_JPG_PROCEED, FILENAME_PDF_AS_P7M ) );
69+
}
70+
71+
@Test
72+
public void testProccedOk() {
73+
Assert.assertEquals( PdfboxStrictValidator.DEFAULT.getMimeType(), this.worker( CONTENT_PDF_PROCEED, FILENAME_PDF_AS_P7M ) );
74+
}
4175

4276
}

0 commit comments

Comments
 (0)