Orbeon Forms
  • Getting started
  • Installation
    • Logging
    • Configuration banner
    • Docker
    • Azure
    • Tomcat
    • WildFly
    • WebSphere
    • WebLogic
    • GlassFish
    • Caches
    • Replication
    • Upgrading
  • Configuration
    • Properties
      • General
        • HTTP client
      • Form Runner
        • Detail page
          • Attachments
          • Email properties
          • PDF
          • Table of contents
        • Persistence
        • Summary page
      • Form Builder
      • XForms
    • Advanced
      • Workflows
      • Session management
      • State handling
      • Client-side error handling
      • Clustering and High Availability
      • Configuring a Form Runner eXist database
      • Creating a production WAR
      • Environments
      • JavaScript and CSS assets
      • Limiter filter
      • Run modes
      • Security
        • Content-Security-Policy header
      • SAP Hybris Module
      • XForms logging
    • Troubleshooting
      • Troubleshooting with the orbeon.log
      • Memory and threads
      • Relational database logging
      • Misc
  • Form Builder
    • Form settings
      • Time window
    • Form editor
      • Form area
      • Toolbox
      • Buttons bar
      • Control settings
      • Dependent fields and sections
      • Validation
      • Choices editor
      • Publishing
      • Cut, copy and paste
      • Section and grid settings
      • Section settings
      • Grid settings
      • Quick control search
      • Repeat settings
      • Repeated grids
      • Undo and redo
      • Keyboard shortcuts
    • Formulas
      • Examples of formulas
      • Formulas inspector
      • Formulas console
    • Summary page
    • Form localization
    • Advanced
      • Edit source
      • Services and actions
        • HTTP services
        • Database services
        • Simple Actions
        • Action Syntax
        • Action Syntax examples
        • Synchronizing repeated content
      • Testing a form in web mode
      • Testing PDF production
      • Testing offline functionality
      • Email Settings dialog
      • Field-level encryption
      • Messages
      • Section templates
      • Template syntax
      • XML Schemas support
      • Extensibility
        • Extension API
        • Integration
        • Toolbox component metadata
  • Form Runner
    • Overview
      • Terminology
    • Pages
      • Landing page
      • Published Forms page
      • Forms Admin page
      • Summary page
    • Components
      • Alert dialog
      • Attachment
      • Autocomplete
      • Captcha
      • Character counter
      • Checkbox input
      • Currency
      • Date
      • Dropdown date
      • Static and dynamic dropdown
      • Error summary
      • Grid
      • Handwritten signature
      • Hidden field
      • Image
      • Image annotation
      • Image attachment
      • International Securities Identification Number (ISIN)
      • Legal Entity Identifier (LEI)
      • Number
      • Open selection
      • Repeater
      • Formatted Text / Rich Text Editor
      • Section
      • Single-selection tree
      • Source code editor
      • Time
      • US Employer Identification Number (EIN)
      • US phone
      • US Social Security Number (SSN)
      • US state
      • Video
      • Video attachment
      • Wizard
      • XForms inspector
      • Yes/No answer
    • Features
      • Automatic calculations dependencies
      • Datasets
      • Excel and XML import
      • Excel and XML export
      • Summary page Excel Export
      • Form definitions and form data Zip Export
      • Purging historical data
      • Lease
      • Localization
      • Supported languages
      • Mobile support
      • Multitenancy
      • Form Runner navigation bar
      • PDF production
        • Automatic PDF
        • Automatic PDF header and footer configuration
        • PDF templates
      • Responsive design
      • Revision history
      • S3 storage
      • Simple data migration
      • TIFF production
      • Versioning
      • Wizard view
      • Workflow stage
    • Persistence
      • Using a relational database
      • Relational database schema
      • Purging old data using SQL
      • Auditing
      • Autosave
      • Database support
      • Flat view
    • Linking and embedding
      • Linking
      • Java Embedding API
      • JavaScript Embedding API
      • Liferay full portlet
      • Liferay proxy portlet
      • Securing Form Runner access
      • Form Runner offline embedding API
      • Angular component
      • React component
    • Access control and permissions
      • Users
      • Login & Logout
      • Deployed forms
      • Form fields
      • Editing forms
      • Owner and group member
      • Organizations
      • Scenarios
      • Token-based permissions
    • Styling
      • CSS
      • Grids CSS
      • Automatic PDF styling and CSS
    • APIs
      • Authentication of server-side service APIs
      • Persistence API
        • CRUD API
        • Search API
        • List form data attachments API
        • Form Metadata API
        • Lease API
        • Reindexing API
        • Caching
        • Versioning
        • Revision History API
        • Zip Export API
        • Custom persistence providers
      • Other APIs
        • Connection context API
        • Duplicate form data API
        • File scan API
        • Form Runner JavaScript API
        • Generate XML Schema API
        • PDF API
        • Publish form definition API
        • Run form in the background API
      • Data formats
        • Form data
        • Date and time
        • Form definition
    • Architecture and integration
      • Architecture
      • Access form data
      • Integration
    • Advanced
      • Buttons and processes
        • Simple process syntax
        • Core actions
        • Form Runner actions
          • Save action
          • Send action
          • Email action
        • XForms actions
        • Predefined buttons, processes and dialogs
        • Summary page buttons and processes
      • Custom dialogs/model logic
      • Services
      • Singleton form
      • Monitoring HTTP requests
  • XForms
    • Core
      • Attribute Value Templates (AVTs)
      • Binds
      • Validation
      • Variables
      • Keyboard focus
      • XForms JavaScript API
      • Error handling
        • Detailed behavior
      • Model-Bind variables
      • XForms 2.0 support
    • Events
      • Standard support
      • UI refresh events
      • Keyboard events
      • Extension events
      • Extension context information
      • Other event extensions
    • Actions
      • Repeat, insert and delete
      • Scripting actions
      • Extensions
    • Controls
      • Label, hint, help
      • Input
      • Output
      • Text area
      • Button
      • Upload
      • Dialog
    • Submission
      • Standard support
      • JSON support
      • Asynchronous submissions
      • Caching extension
      • Other submission extensions
    • XPath
      • Type annotations
      • Expression analysis
      • Tips
      • Compatibility
      • Standard functions
      • Maps and arrays Functions
      • Extension functions
        • Core functions
        • Utility functions
        • Model functions
        • Controls functions
        • XML functions
        • JSON functions
        • HTTP functions
        • Form Runner functions
        • Other functions
        • Deprecated functions
    • XBL components
      • FAQ
      • Guide
        • XBL Tutorial
        • Bindings
        • XForms models
        • Including content
        • Event handling
        • Conventions
        • Map XBL example
        • Learning from existing components
      • Advanced topics
        • XBL Modes
        • JavaScript companion classes
        • XBL library
        • Extensions
        • Attachment controls
    • XForms tutorial
      • Introduction
      • Installation
      • The Hello application
      • The Bookcast application
        • The basic app
        • Database access
        • Polishing the app
        • Adding a feed
    • Using XForms from Java apps
  • XML Platform
    • Page Flow Controller
      • Basics
      • XML submission
      • Navigating between pages
      • Paths and matchers
      • Other configuration elements
      • Typical combinations of page model and page view
      • Examples
      • Authorizing pages and services
    • Processors
      • URL generator
      • Request generator
      • PDF to image converter
    • Resources
      • Resource managers
      • Setting up an external resources directory
    • Other
      • Binary and text documents
  • FAQ
    • Licensing
    • PE and Dev Support
    • Form Builder and Form Runner
    • Resources and support
    • Other technical questions
  • Contributors
    • Automated tests
    • Building Orbeon Forms
    • Localizing Orbeon Forms
    • Validation functions
    • Contributor License Agreement
  • Release notes
    • Orbeon Forms 2022.1.9
    • Orbeon Forms 2024.1.1
    • Orbeon Forms 2023.1.7
    • Orbeon Forms 2024.1
    • Orbeon Forms 2023.1.6
    • Orbeon Forms 2023.1.5
    • Orbeon Forms 2021.1.11
    • Orbeon Forms 2022.1.8
    • Orbeon Forms 2023.1.4
    • Orbeon Forms 2023.1.3
    • Orbeon Forms 2023.1.2
    • Orbeon Forms 2022.1.7
    • Orbeon Forms 2023.1.1
    • Orbeon Forms 2023.1
    • Orbeon Forms 2022.1.6
    • Orbeon Forms 2021.1.10
    • Orbeon Forms 2022.1.5
    • Orbeon Forms 2021.1.9
    • Orbeon Forms 2022.1.4
    • Orbeon Forms 2022.1.3
    • Orbeon Forms 2021.1.8
    • Orbeon Forms 2022.1.2
    • Orbeon Forms 2022.1.1
    • Orbeon Forms 2022.1
    • Orbeon Forms 2021.1.7
    • Orbeon Forms 2021.1.6
    • Orbeon Forms 2021.1.5
    • Orbeon Forms 2021.1.4
    • Orbeon Forms 2021.1.3
    • Orbeon Forms 2021.1.2
    • Orbeon Forms 2021.1.1
    • Orbeon Forms 2021.1
    • Orbeon Forms 2020.1.6
    • Orbeon Forms 2019.2.4
    • Orbeon Forms 2019.1.2
    • Orbeon Forms 2018.2.5
    • Orbeon Forms 2018.1.4
    • Orbeon Forms 2020.1.5
    • Orbeon Forms 2020.1.4
    • Orbeon Forms 2020.1.3
    • Orbeon Forms 2020.1.2
    • Orbeon Forms 2019.2.3
    • Orbeon Forms 2020.1.1
    • Orbeon Forms 2020.1
    • Orbeon Forms 2019.2.2
    • Orbeon Forms 2019.2.1
    • Orbeon Forms 2019.1.1
    • Orbeon Forms 2019.2
    • Orbeon Forms 2019.1
    • Orbeon Forms 2018.2.4
  • Release history
  • Use cases
  • Product roadmap
  • Index of features
Powered by GitBook
On this page
  • Rationale
  • API Version 2
  • Availability
  • API
  • Registering a provider
  • Example
  • API Version 1
  • Availability
  • API
  • Registering a provider
  • Example
  • See also
  1. Form Runner
  2. APIs
  3. Other APIs

File scan API

Rationale

When a user uploads files via one of the Form Runner attachment controls, a virus scanner can verify the file before it gets attached to the current form.

Orbeon Forms provides a simple Java API which allows integrating with virus scanning solutions.

NOTE: At this time Orbeon doesn't provide integrations with specific virus scanning solutions.

API Version 2

Availability

[SINCE Orbeon Forms 2022.1]

This is an Orbeon Forms PE feature.

Version 2 of the API adds the following enhancements to the original version (called now Version 1):

  • The provider can return a modified file name, content type, or even replace the entire content.

  • The provider can return custom error messages in the current language of the form.

  • An extension mechanism via hash maps is provided.

While we recommend using Version 2 of the API, Version 1 is still supported. If a Version 2 provider is present, it takes precedence over a Version 1 provider.

API

Orbeon Forms provide the following FileScanProvider2 interface as a base for concrete providers:

package org.orbeon.oxf.xforms.upload.api.java;

interface FileScanProvider2 {

  void init();
  void destroy();
  
  FileScan2 startStream(
      String                filename,
      Map<String, String[]> headers,
      String                language,
      Map<String, Object>   extension
  );
}

When Orbeon Forms initializes the provider, it:

  • creates an instance of the class

  • calls the init() method

When Orbeon Forms is starting to receive an upload file, it calls the startStream() method. The method receives:

  • filename: a file name as provided by the web browser (which means that it must not be trusted)

  • headers: HTTP header name/values as they are received by Orbeon Forms

  • language: the current form language at the time the user started the upload

  • extension: an extension immutable hashmap

    • NOTE: This is an empty hashmap from Orbeon Forms 2022.1.0 until 2022.1.4 included.

The extension hashmap contains the following keys and values:

Key
Value type
Description
Since Orbeon Forms Version

request.uri

java.net.URI

path and query of the form containing the attachment

2022.1.5

The java.net.URI associated with request.uri contains the following parts:

Part
Description

getPath()

Orbeon Forms path that loaded the form, for example /fr/acme/order/new or /fr/acme/order/edit/1234

getQuery()

the query string, for example form-version=2

other

set to null

The provider implementation must return an implementation of a FileScan2.

The FileScan2 interface is as follows :

package org.orbeon.oxf.xforms.upload.api.java;

interface FileScan2 {
    FileScanResult bytesReceived(byte[] bytes, int offset, int length);
    FileScanResult complete(File file);
    void abort();
}

The FileScanResult type replaces the earlier API's FileScanStatus:

package org.orbeon.oxf.xforms.upload.api.java;


public abstract class FileScanResult {

    public final String message;

    private FileScanResult(String message) {
        this.message = message;
    }

    public static class FileScanAcceptResult extends FileScanResult {

        public final String                        mediatype;
        public final String                        filename;
        public final java.io.InputStream           content;
        public final java.util.Map<String, Object> extension;

        public FileScanAcceptResult() {
            this(null, null, null, null, null);
        }

        public FileScanAcceptResult(
            String                        message,
            String                        mediatype,
            String                        filename,
            java.io.InputStream           content,
            java.util.Map<String, Object> extension
        ) {
            super(message);
            this.mediatype = mediatype;
            this.filename  = filename;
            this.content   = content;
            this.extension = extension;
        }
    }

    public static class FileScanRejectResult extends FileScanResult {
        public FileScanRejectResult(String message) {
            super(message);
        }
    }

    public static class FileScanErrorResult extends FileScanResult {

        public final Throwable throwable;

        public FileScanErrorResult(String message, Throwable throwable) {
            super(message);
            this.throwable = throwable;
        }
    }
}

This essentially defines three possible results, all implementing FileScanResult:

  • FileScanAcceptResult: accept the uploaded content, possibly with modifications

  • FileScanRejectResult: reject the uploaded content (for example because it is suspected to contain a virus), possibly with a message

  • FileScanErrorResult: any other error happened, possibly with a message and Throwable

As bytes are received, the bytesReceived() method is called. This method allows incremental scanning of a file. A provider may or may not make use of this method. If it is unused, the provider must return a FileScanAcceptResult with all null content, for example with:

public FileScanResult bytesReceived(byte[] bytes, int offset, int length) {
    return new FileScanResult.FileScanAcceptResult();
}

When the file is completely uploaded and stored into a temporary file, but not yet attached to the user's form, the complete() method is called with a pointer to the temporary file. The scanner can use this method to perform the entirety of the scan in case bytesReceived() is not used.

Upon processing the complete() method, resources associated with the file scan must be cleared by the provider, whether FileScanRejectResult or FileScanErrorResult is returned, or if any exception is thrown as part of the processing of complete().

Both bytesReceived() and complete() must return a value from the FileScanStatus enumeration:

If FileScanRejectResult or FileScanErrorResult is returned, or if any exception is thrown as part of startStream(), bytesReceived(), or complete(), the uploaded file is rejected and an error is shown to the user.

If the user cancels the upload, or if any other error occurs on the Orbeon Forms side, the abort() method is called. In this case, the file scan for the given file must be stopped and associated resources must be cleared, if any.

The abort() method may be called after the complete() method.

The constructor parameters for FileScanAcceptResult, FileScanRejectResult, and FileScanErrorResult can all be set to null.

If the provider wants to accept the file but replace any of the following:

  • filename

  • mediatype

  • actual content

It can do so with a FileScanAcceptResult response, simply by passing non-null values to the respective fields in the constructor.

Replacing the entire content of the uploaded file is useful for example to:

  • strip metadata in images

  • recompress images (although there is a built-in Orbeon Forms feature for that)

  • standardize file formats

Registering a provider

The provider must:

  • be a public class

  • have a public no-arguments constructor

  • implement the FileScanProvider2 Java interface

To enable a provider with Orbeon Forms:

  • create a JAR file containing the code or your provider

  • place your JAR file under the Orbeon Forms WEB-INF/lib directory

The Orbeon Forms log files will log errors if any when starting if the provider was found but could not be instantiated.

Example

  • log method calls

  • reject files which contain in their name the string "virus"

  • replace files which contain in their name the string "replace"

  • prefix the file name with "My "

  • return messages in English and French

NOTE: This obviously is not the right way to determine whether a file contains a virus or not!

API Version 1

Availability

[SINCE Orbeon Forms 2017.2]

This is an Orbeon Forms PE feature.

API

Orbeon Forms provide the following FileScanProvider abstract class as a base for concrete providers:

package org.orbeon.oxf.xforms.upload.api.java;

public abstract class FileScanProvider {

    public void init();
    public void destroy();

    public FileScan startStream(String filename, Map<String, String[]> headers);
}

When Orbeon Forms initializes the provider, it:

  • creates an instance of the class

  • calls the init() method

When Orbeon Forms is starting to receive an upload file, it calls the startStream() method. The method receives a file name as provided by the web browser (which means that it must not be trusted), and HTTP header name/values as they are received by Orbeon Forms.

The provider implementation must return an implementation of a FileScan.

The FileScan interface is as follows :

package org.orbeon.oxf.xforms.upload.api.java;

interface FileScan {
    FileScanStatus bytesReceived(byte[] bytes, int offset, int length);
    FileScanStatus complete(File file);
    void abort();
}

As bytes are received, the bytesReceived() method is called. A provider may or may not make use of this method. If it is unused, the provider must return an ACCEPT FileScanStatus (see below). This method allows incremental scanning of a file.

When the file is completely uploaded and stored into a temporary file, but not yet attached to the user's form, the complete() method is called with a pointer to the temporary file. The scanner can use this method to perform the entirety of the scan in case bytesReceived() is not used.

Upon processing the complete() method, resources associated with the file scan must be cleared by the provider, whether REJECT or ERROR is returned, or if any exception is thrown as part of the processing of complete().

Both bytesReceived() and complete() must return a value from the FileScanStatus enumeration:

package org.orbeon.oxf.xforms.upload.api.java;

public enum FileScanStatus { ACCEPT, REJECT, ERROR }
  • ACCEPT: accept the uploaded content

  • REJECT: reject the uploaded content (for example because it is suspected to contain a virus)

  • ERROR: any other error happened

If REJECT or ERROR is returned, or if any exception is thrown as part of startStream(), bytesReceived(), or complete(), the uploaded file is rejected and an error is shown to the user.

If the user cancels the upload, or if any other error occurs on the Orbeon Forms side, the abort() method is called. In this case, the file scan for the given file must be stopped and associated resources must be cleared, if any.

The abort() method may be called after the complete() method.

Registering a provider

The provider must:

  • be a public class

  • have a public no-arguments constructor

  • extend the FileScanProvider Java abstract class

To enable a provider with Orbeon Forms:

  • create a JAR file containing the code or your provider

  • place your JAR file under the Orbeon Forms WEB-INF/lib directory

The Orbeon Forms log files will log errors if any when starting if the provider was found but could not be instantiated.

Example

  • log method calls

  • reject files which contain in their name the string "virus"

NOTE: This obviously is not the right way to determine whether a file contains a virus or not.

See also

PreviousDuplicate form data APINextForm Runner JavaScript API

Last updated 1 year ago

The file scan API uses the standard Java API with a provider name of org.orbeon.oxf.xforms.upload.api.java.FileScanProvider2.

create your provider as per the standard Java

is a Java example of a provider which does nothing but:

The service provider is described with this file.

The example project is provided .

The file scan API uses the standard Java API with a provider name of org.orbeon.oxf.xforms.upload.api.FileScanProvider.

create your provider as per the standard Java

is a Java example of a provider which does nothing but:

The service provider is described with this file.

The example project is provided .

ServiceLoader
ServiceLoader
AcmeFileScanProvider2
META-INF/services/org.orbeon.oxf.xforms.upload.api.java.FileScanProvider2
here
ServiceLoader
ServiceLoader
AcmeFileScanProvider
META-INF/services/org.orbeon.oxf.xforms.upload.api.FileScanProvider
here
Connection context API
Form Runner APIs
File scan error
File scan error