Skip to content

Added DocValidatorTypeCheck facade #261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- [fj-doc-val-core] DocValidatorTypeCheck facade to check file type
- [fj-doc-val-p7m] check the inner type on P7MContentValidator

### Changed

- [fj-doc-playground-quarkus] show quakus version
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.fugerit.java.doc.val.core;

import lombok.Getter;
import org.fugerit.java.core.function.SafeFunction;
import org.fugerit.java.core.io.StreamIO;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
* This facade tries to retrieve a document's type.
*
*/
public class DocValidatorTypeCheck {

@Getter
private DocValidatorFacade facade;

private DocValidatorTypeCheck( DocValidatorFacade facade ) {
this.facade = facade;
}

/**
* Type check of a byte stream against the configured DocTypeValidator facade.
*
* 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.
*
* NOTE: This method always buffer the input, so it can be memory consuming.
*
* @param is the byte stream to check
* @return <code>null</code> if the stream is not valid for all the validators, otherwise DocTypeValidator.getMimeType() of the first validator matching the type
*/
public String checkType(InputStream is) {
return SafeFunction.get( () -> this.checkType( StreamIO.readBytes( is ) ) );
}

/**
* Type check for an input document against the configured DocTypeValidator facade.
*
* 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.
*
* NOTE: This method always buffer the input, so it can be memory consuming.
*
* @param buffer the document to check
* @return <code>null</code> if the input is not valid for all the validators, otherwise DocTypeValidator.getMimeType() of the first validator matching the type
*/
public String checkType(byte[] buffer) {
return SafeFunction.get( () -> {
for ( DocTypeValidator validator : this.facade.validators() ) {
try (ByteArrayInputStream input = new ByteArrayInputStream( buffer )) {
if ( validator.check( input ) ) {
return validator.getMimeType();
}
}
}
// default case, type not found
return null;
} );
}

public static DocValidatorTypeCheck newInstance( DocTypeValidator... validator ) {
return newInstance( DocValidatorFacade.newFacadeStrict( validator ) );
}

public static DocValidatorTypeCheck newInstance( DocValidatorFacade facade ) {
return new DocValidatorTypeCheck( facade );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package test.org.fugerit.java.doc.core.val;

import lombok.extern.slf4j.Slf4j;
import org.fugerit.java.core.function.SafeFunction;
import org.fugerit.java.core.lang.helpers.ClassHelper;
import org.fugerit.java.doc.val.core.DocValidatorTypeCheck;
import org.fugerit.java.doc.val.core.basic.ImageValidator;
import org.junit.Assert;
import org.junit.Test;

import java.awt.*;
import java.io.InputStream;

@Slf4j
public class TestDocValidatorTypeCheck {

private static final DocValidatorTypeCheck TYPE_CHECK = DocValidatorTypeCheck.newInstance(
ImageValidator.JPG_VALIDATOR, ImageValidator.PNG_VALIDATOR );

private static final String BASE_PATH = "sample";

private String worker( String fileName ) {
return SafeFunction.get( () -> {
String path = BASE_PATH+"/"+fileName;
log.info( "test path {}", path );
try ( InputStream is = ClassHelper.loadFromDefaultClassLoader( path ) ) {
return TYPE_CHECK.checkType( is );
}
} );
}

@Test
public void testJpg() {
Assert.assertEquals(ImageValidator.JPG_VALIDATOR.getMimeType(), this.worker( "jpg_as_jpg.jpg" ) );
}

@Test
public void testPng() {
Assert.assertEquals(ImageValidator.PNG_VALIDATOR.getMimeType(), this.worker( "png_as_png.png" ) );
}

@Test
public void testNull() {
Assert.assertNull( this.worker( "pdf_as_jpg.jpg" ) );
}

}
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
package org.fugerit.java.doc.val.p7m;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import org.fugerit.java.core.cfg.ConfigRuntimeException;
import org.fugerit.java.core.function.SafeFunction;
import org.fugerit.java.doc.val.core.DocTypeValidationResult;
import org.fugerit.java.doc.val.core.DocTypeValidator;
import org.fugerit.java.doc.val.core.DocValidatorFacade;
import org.fugerit.java.doc.val.core.DocValidatorTypeCheck;
import org.fugerit.java.doc.val.core.basic.AbstractDocTypeValidator;

import lombok.Getter;
import lombok.Setter;

public class P7MContentValidator extends AbstractDocTypeValidator {

public static final boolean DEFAULT_PROCEED_ON_INNTER_CHECK = Boolean.FALSE;

@Getter @Setter private DocValidatorTypeCheck facade;

@Getter private boolean proceedOnInnerTypeCheck;

@Getter @Setter private DocValidatorFacade facade;

public P7MContentValidator(DocValidatorFacade facade) {
public P7MContentValidator(DocValidatorFacade facade, boolean proceedOnInnerTypeCheck) {
super( P7MValidator.MIME_TYPE, P7MValidator.EXTENSION );
this.facade = facade;
this.facade = DocValidatorTypeCheck.newInstance( facade );
this.proceedOnInnerTypeCheck = proceedOnInnerTypeCheck;
}

public P7MContentValidator(DocValidatorFacade facade) {
this( facade, DEFAULT_PROCEED_ON_INNTER_CHECK );
}

public P7MContentValidator() {
Expand All @@ -28,34 +37,43 @@ public P7MContentValidator() {

@Override
public DocTypeValidationResult validate(InputStream is) {
return this.validationHelper( () -> {
return this.validationHelper( () -> this.checkInnerType( is ) );
}

public String checkInnerType(InputStream is ) {
return SafeFunction.get( () -> {
try ( ByteArrayOutputStream os = new ByteArrayOutputStream() ) {
P7MUtils.extractContent(is, os);
if ( this.getFacade() != null ) {
boolean isValid = false;
for ( DocTypeValidator validator : this.getFacade().validators() ) {
try ( ByteArrayInputStream bis = new ByteArrayInputStream( os.toByteArray() ) ) {
if ( validator.check( bis ) ) {
isValid = true;
break;
}
}
}
if ( !isValid ) {
if ( this.facade.getFacade() != null ) {
String mimeType = this.facade.checkType( os.toByteArray() );
if ( mimeType != null || this.proceedOnInnerTypeCheck ) {
return mimeType;
} else {
throw new ConfigRuntimeException( "Content not valid for this validator facade!" );
}
} else {
return null;
}
}
} );
}

public P7MContentValidator withDocValidatorFacade( DocValidatorFacade facade ) {
this.setFacade( facade );
this.setFacade( DocValidatorTypeCheck.newInstance( facade ) );
return this;
}


public P7MContentValidator withProceedOnInnerTypeCheck( boolean proceedOnInnerTypeCheck ) {
this.proceedOnInnerTypeCheck = proceedOnInnerTypeCheck;
return this;
}

public static P7MContentValidator newValidator( DocValidatorFacade facade ) {
return new P7MContentValidator().withDocValidatorFacade(facade);
return newValidator( facade, DEFAULT_PROCEED_ON_INNTER_CHECK );
}

public static P7MContentValidator newValidator( DocValidatorFacade facade, boolean proceedOnInnerTypeCheck ) {
return new P7MContentValidator().withDocValidatorFacade(facade).withProceedOnInnerTypeCheck( proceedOnInnerTypeCheck );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

import java.io.InputStream;

import lombok.extern.slf4j.Slf4j;
import org.fugerit.java.core.function.SafeFunction;
import org.fugerit.java.core.lang.helpers.ClassHelper;
import org.fugerit.java.doc.val.core.DocValidatorFacade;
import org.junit.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Slf4j
public class TestDocValidatorFacade {

private static final Logger logger = LoggerFactory.getLogger( TestDocValidatorFacade.class );

private static final String BASE_PATH = "sample";
protected static final String BASE_PATH = "sample";

protected boolean worker( DocValidatorFacade facade, String fileName, boolean result ) {
return SafeFunction.get( () -> {
String path = BASE_PATH+"/"+fileName;
logger.info( "test path {}, expected result {}", path, result );
log.info( "test path {}, expected result {}", path, result );
try ( InputStream is = ClassHelper.loadFromDefaultClassLoader( path ) ) {
boolean check = facade.check(fileName, is);
Assert.assertEquals( "File check failed", result, check );
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package test.org.fugerit.java.doc.val.p7m;

import lombok.extern.slf4j.Slf4j;
import org.fugerit.java.core.function.SafeFunction;
import org.fugerit.java.core.lang.helpers.ClassHelper;
import org.fugerit.java.doc.val.core.DocValidatorFacade;
import org.fugerit.java.doc.val.core.basic.ImageValidator;
import org.fugerit.java.doc.val.p7m.P7MContentValidator;
import org.fugerit.java.doc.val.pdf.box.PdfboxStrictValidator;
import org.junit.Assert;
import org.junit.Test;

import java.io.InputStream;

@Slf4j
public class TestP7MContentValidator extends TestDocValidatorFacade {

private static final String FILENAME_PDF_AS_P7M = "pdf_as_pdf.p7m";

private static final DocValidatorFacade FACADE_PDF = DocValidatorFacade.newFacadeStrict(
P7MContentValidator.newValidator( DocValidatorFacade.newFacade( PdfboxStrictValidator.DEFAULT ) )
);
Expand All @@ -20,23 +28,49 @@ public class TestP7MContentValidator extends TestDocValidatorFacade {
private static final DocValidatorFacade FACADE_NULL = DocValidatorFacade.newFacadeStrict(
P7MContentValidator.newValidator( null )
);

private static final P7MContentValidator CONTENT_JPG_PROCEED =
P7MContentValidator.newValidator( DocValidatorFacade.newFacade( ImageValidator.JPG_VALIDATOR ), true );

private static final P7MContentValidator CONTENT_PDF_PROCEED =
P7MContentValidator.newValidator( DocValidatorFacade.newFacade( PdfboxStrictValidator.DEFAULT ), true );

protected String worker( P7MContentValidator validator, String fileName ) {
return SafeFunction.get( () -> {
String path = BASE_PATH+"/"+fileName;
log.info( "test path to check {}", path );
try ( InputStream is = ClassHelper.loadFromDefaultClassLoader( path ) ) {
return validator.checkInnerType( is );
}
} );
}

@Test
public void testP7MAsP7M() {
boolean ok = this.worker(FACADE_PDF, "pdf_as_pdf.p7m", true );
boolean ok = this.worker(FACADE_PDF, FILENAME_PDF_AS_P7M, true );
Assert.assertTrue( ok );
}

@Test
public void testP7MAsP7MNull() {
boolean ok = this.worker(FACADE_NULL, "pdf_as_pdf.p7m", true );
boolean ok = this.worker(FACADE_NULL, FILENAME_PDF_AS_P7M, true );
Assert.assertTrue( ok );
}

@Test
public void testP7MAsP7MKo() {
boolean ok = this.worker(FACADE_JPG, "pdf_as_pdf.p7m", false );
boolean ok = this.worker(FACADE_JPG, FILENAME_PDF_AS_P7M, false );
Assert.assertTrue( ok );
}

@Test
public void testProccedKo() {
Assert.assertNull( this.worker( CONTENT_JPG_PROCEED, FILENAME_PDF_AS_P7M ) );
}

@Test
public void testProccedOk() {
Assert.assertEquals( PdfboxStrictValidator.DEFAULT.getMimeType(), this.worker( CONTENT_PDF_PROCEED, FILENAME_PDF_AS_P7M ) );
}

}