adm_pdf_api
Operations on PDF documents: read the page count, merge, split, watermark, protect with a password, render the pages as images, put text, images, comments and page numbers on the pages, read, fill and flatten form fields, take the file attachments out of a PDF and put attachments in, check that a PDF is sound, and convert Word, Excel, PowerPoint, text, CSV, HTML and Markdown documents to PDF. Every operation takes the ID of a document and, where it makes a new file, stores the result as a new document. The source documents do not change.
The work is done by APEX Office Print (AOP). The AOP URL and key are in the
configuration (settings AOP_API_URL and AOP_API_KEY). Without a URL every operation
raises adm_error.e_aop_not_configured, after the checks below and when the call is about
to reach AOP. The operations are synchronous: the call waits for AOP.
Every operation runs as the current ADM context user and checks the rights of that user before a file is read or sent to AOP:
- The user needs view rights on every source document. A document that is deleted or
does not exist raises
adm_error.e_doc_not_found. - The user needs edit rights on the folder that gets the result.
- With
p_overwrite, the user also needs edit rights on the document that gets the new version.
A failed check raises adm_error.e_no_permission.
Embed sessions. Outside an embed session, view rights are also the right to download a
file. In an embed session, a token can show a document without the right to take it out.
An operation reads the source and stores a copy, and that takes the content out. So in an
embed session the token must also hold these grants. Without one, the call raises
adm_error.e_no_permission before a file is read or sent:
DOWNLOADfor every source document. This includes the images ofadd_image, the documents thatadd_attachmentsputs in the PDF, and it includesget_page_count,get_info,get_form_fieldsandvalidate.UPLOADfor a new result document.UPLOAD_VERSIONwhenp_overwriteadds a version to an existing document.
A token without a write grant has no edit rights on a folder, so it cannot store a result.
The grants UPLOAD and UPLOAD_VERSION also stop a token that has only another write
grant, for example MOVE.
What else every operation checks, in this order, before a file leaves the database:
- Every source document is a PDF (
adm_error.e_not_a_pdf). The images ofadd_imageare PNG or JPEG documents (adm_error.e_not_supported). The documents thatadd_attachmentsputs in the PDF can be of any type.validatedoes not look at the type: it looks at the content. The source ofconvert_to_pdfis the other way round: it is not a PDF, and its type is one that AOP can convert (adm_error.e_not_supported). - The total size of all source files of the call is not larger than the setting
PDF_MAX_FILE_SIZE_MB (
adm_error.e_limit_exceeded). The default is 50 MB. An image counts once for every place whereadd_imageputs it, because ADM sends it once for every place. The attachments ofadd_attachmentscount with their size. The files thatget_attachmentstakes out of a PDF also count: together they are not larger than the limit. - No source PDF is protected with a password (
adm_error.e_pdf_encrypted). AOP cannot read such a file. - No source PDF has a digital signature (
adm_error.e_pdf_signed). This check is only for the operations that make a new PDF from the source:merge,split,watermark,protect,add_text,add_image,add_comments,add_page_numbers,fill_form,flatten_formandadd_attachments. AOP writes a whole new file for each of them, and a change of one byte makes every signature invalid. The call refuses a signed source, unless you passp_invalidate_signatures => true. Then no signature of a source covers the whole file of the result, and the audit entry says how many signatures the sources had. Most operations leave the old signature data in the file, and the signature is not valid.fill_formappends to the file, so the old signature stays valid for the old bytes and does not cover the whole file. Seeget_provenance. In a folder with the signing modeSIGNa source that ADM signed is not refused, see Auto-sign below. The operations that only read (get_page_count,get_info,get_form_fields,get_attachments,validateandto_images) work on a signed PDF.get_inforeports the signatures. The check looks at the bytes of the file (seeget_info), and it is made after the rights, because it needs the content.
Auto-sign. When the result goes to a folder with the signing mode SIGN (see
adm_signing_policy_api), ADM signs the result with the key of the setting
AUTO_SIGN_KEY_ID before it stores it. The document gets one version, and it is signed.
This is for merge, split (every part), watermark, add_text, add_image,
add_comments, add_page_numbers, fill_form, flatten_form, add_attachments and
convert_to_pdf. protect, sign, to_images and get_attachments are not signed. In a
folder with the mode OFF or WATCH the operations work as described above. The saves of the
built-in PDF editor are signed with the same rules, see get_editor_signature_info.
- The user needs no grant of the key, and an embed session can do it: ADM signs for the system. There is no call for this signature. ADM makes it inside the operation.
- Fail closed. The key must be active and its certificate valid now, and AOP must be
26.1.2 or later. This is checked before a file is read
(
adm_error.e_signing_key_unusable,adm_error.e_aop_too_old). A failure of the signature fails the operation, and nothing is stored. - A source that ADM signed (
get_provenanceisADM_SIGNED) needs nop_invalidate_signatures: the new signature replaces the old one. When the source has one signature, AOP gets the file as it was before that signature (the unsigned base), so nothing of the old signature is left in the result. Any other signed source is refused as described in check 4, unless you passp_invalidate_signatures => true. - A source with two or more valid signatures raises
adm_error.e_auto_sign_multi_signedbefore it is sent to AOP. AOP cannot sign a changed copy of such a file. - The audit entry of the result names the key, the SHA-256 of the file before and after
the signature and the signed digest, like the entry of
sign. After the store the hookAFTER_PDF_SIGNEDruns, unlessp_run_hooksis false. The new version gets the statusADM_SIGNED, unless a hook changes the file.
With the provider DATABASE everyone who can run code as the owner of the ADM schema can
sign with the key. Use Transit or OCI Vault when the signature has to prove something.
A failure of AOP itself raises adm_error.e_pdf_operation_failed. For convert_to_pdf
it raises adm_error.e_conversion_failed. The text of the AOP error is in the log and
not in the message.
Names of the results. If you do not pass a name, the name comes from the first source
document. The extension .pdf of the source is replaced:
| Operation | Source report.pdf |
Result |
|---|---|---|
merge |
report.pdf |
report (merged).pdf |
watermark |
report.pdf |
report (watermarked).pdf |
protect |
report.pdf |
report (protected).pdf |
add_text |
report.pdf |
report (text).pdf |
add_image |
report.pdf |
report (image).pdf |
add_comments |
report.pdf |
report (comments).pdf |
add_page_numbers |
report.pdf |
report (numbered).pdf |
fill_form |
report.pdf |
report (filled).pdf |
flatten_form |
report.pdf |
report (flattened).pdf |
add_attachments |
report.pdf |
report (attachments).pdf |
convert_to_pdf |
report.docx |
report.pdf |
split |
report.pdf |
report (part 1).pdf, report (part 2).pdf, … |
to_images |
report.pdf |
report (page 1).jpg, report (page 2).jpg, … |
get_attachments |
report.pdf |
The names inside the PDF, for example invoice.xml |
A name that is already used by a document in the target folder:
- You did not pass a name, and
p_overwriteis false (the default). The name gets a number:report (watermarked).pdf,report (watermarked) (2).pdf,report (watermarked) (3).pdfand so on. The call uses the first number that is free. The number is in front of the extension. A name that is too long is cut in front of the suffix, and the number stays. A call does not use more than 1000 numbers: then it raisesadm_error.e_doc_exists. - You did not pass a name, and
p_overwriteis true. The result becomes a new version of the existing document with the derived name, without a number. That document must be a PDF, or the call raisesadm_error.e_doc_exists. - You passed a name (
p_document_name). Withp_overwrite => falsethe call raisesadm_error.e_doc_exists, and no document is created. Withp_overwrite => truethe result becomes a new version of the existing document. The existing document must be a PDF. ADM does not add a number to a name that you passed. - A new version from
p_overwriteis never merged into the latest version, whatever the settingVERSION_MERGE_WINDOW_MINUTESsays and whoever saved last: the file that the operation started from stays in the history. convert_to_pdfhas no suffix: the extension of the source is replaced. A name that is used gets a number as above:report.pdf,report (2).pdf. Withp_overwrite => true, a derived name that belongs to a PDF gets a new version. A derived name that belongs to a document that is not a PDF gets a number, so the call never adds a version to such a document. A name that you pass follows the rules above, with one exception: the name that the call derives from the source is the same as no name. The page “Convert to PDF” passes it to show it to the user.splitandto_imagesmake many documents and have nop_overwriteand no name. All results of one call get the same number. If a name likereport (part 2).pdfis used, the call uses the first number for which all names are free:report (part 1) (2).pdf,report (part 2) (2).pdf, … The names are chosen when AOP has made the files, and before the first document is made.get_attachmentsmakes documents with the names of the attachments. It has nop_overwriteand no name. If one of the names is used in the folder, all results get the same number in front of the extension:invoice.xmlandscan.pngbecomeinvoice (2).xmlandscan (2).png.
ADM chooses a name and then makes the document. If another session makes a document
with the same name between the two steps, adm_error.e_doc_exists is raised, or the
error of the unique index ADM_DOCUMENTS_LIVE_NAME_UK. The call does not try again. For
split and to_images, results that the call made before the failure are in the
transaction. Roll back the transaction and call again.
Hooks. Every result is a new document, or a new version, and runs the hooks of ADM
(AFTER_NEW_FILE_UPLOAD or AFTER_NEW_FILE_VERSION) like any upload. A hook that calls
one of these operations on the file that it received makes a new document, and that
document runs the hook again. The hooks stop at a depth of 10 with
adm_error.e_hook_depth_exceeded. A hook that calls these operations must pass
p_run_hooks => false. Only an administrator or the system user can pass false. Any
other user raises adm_error.e_admin_required, before a file is read or sent. Then
a hook for ordinary users puts the work in a queue, and a worker that has a system context
calls the operation. The call waits for AOP, so when AOP is down, the hook fails, and
the upload that started the hook fails with it.
The package never commits and never rolls back. When a call raises an error, the caller decides about the transaction.
Example: make a watermarked copy and read its page count
declare l_document_id adm_documents.document_id%type;begin l_document_id := adm_pdf_api.watermark( p_document_id => 1234 , p_text => 'DRAFT' ); dbms_output.put_line(adm_pdf_api.get_page_count(l_document_id));end;t_text_overlay
Section titled “t_text_overlay”One text for add_text. Only text, x and y are required. A field that you leave
null has the default of AOP: 12 points, Arial and black.
The position is in points (1 point is 1/72 inch), from the lower left corner of the page.
x and y are the lower left corner of the first character, on the baseline. A page
of the size A4 is 595 points wide and 842 points high. Both values are 0 or more.
The fields for text, font and color are longer than their limits, so that a value that
is too long raises adm_error.e_invalid_param with a clear message and not an error of
the PL/SQL assignment.
The text is one line. A line break in the text is refused. The characters of the text
can be any Unicode character. A character that the font does not have is shown in
another font. The text can hold the placeholders {currentpage} and {totalpage}. AOP
replaces them on every page.
Definition:
type t_text_overlay is record ( page pls_integer -- Page number from 1. Null: every page., text varchar2(4000 char) -- The text. Required. Up to 1000 characters., x number -- Required. Points from the left edge., y number -- Required. Points from the bottom edge., font varchar2(4000 char) -- Name of the font up to 100 characters. For example Arial., font_size number -- Size in points. More than 0., color varchar2(100 char) -- Hexadecimal color. For example #ff0000., rotation number -- Angle in degrees. Positive is counterclockwise., bold boolean -- True for bold. Null is false., italic boolean -- True for italic. Null is false.);Fields:
| Name | Type | Description |
|---|---|---|
page |
pls_integer |
Page number from 1. Null: every page. |
text |
varchar2(4000 char) |
The text. Required. Up to 1000 characters. |
x |
number |
Required. Points from the left edge. |
y |
number |
Required. Points from the bottom edge. |
font |
varchar2(4000 char) |
Name of the font up to 100 characters. For example Arial. |
font_size |
number |
Size in points. More than 0. |
color |
varchar2(100 char) |
Hexadecimal color. For example #ff0000. |
rotation |
number |
Angle in degrees. Positive is counterclockwise. |
bold |
boolean |
True for bold. Null is false. |
italic |
boolean |
True for italic. Null is false. |
t_text_overlays
Section titled “t_text_overlays”The texts of add_text. Fill it with any index, for example
l_texts(1).text := 'Approved';. The order does not matter.
Definition:
type t_text_overlays is table of t_text_overlay index by pls_integer;t_image_overlay
Section titled “t_image_overlay”One image for add_image. The image is a PNG or a JPEG document of ADM. The user needs
view rights on it, like on every source document. A PNG can have transparent areas.
The position is in points from the lower left corner of the page. x and y are the
lower left corner of the image. Give width, height or both:
- One of them: the other one follows from the proportions of the image.
- Both, and
keep_aspect_ratiois not true: the image is stretched to the size. - Both, and
keep_aspect_ratiois true: the image gets the largest size that fits in the area, and the proportions stay.
Without width and height the call raises adm_error.e_invalid_param: AOP does not
use the size of the image file and draws 50 by 50 points.
Order. ADM draws the images of a page in the order of the collection, but the images with
an opacity below 1 come after the others. If it did not, AOP would draw every image that
follows a transparent image in the wrong place. For the same reason an image with an
opacity below 1 and no page cannot be in the same call as an image with a page. The call
raises adm_error.e_invalid_param. Give the transparent image a page, or use two calls.
Definition:
type t_image_overlay is record ( page pls_integer -- Page number from 1. Null: every page., document_id adm_documents.document_id%type -- The image document. Required., x number -- Required. Points from the left edge., y number -- Required. Points from the bottom edge., width number -- Width in points. More than 0., height number -- Height in points. More than 0., keep_aspect_ratio boolean -- With width and height: fit the image in the area., rotation number -- Angle in degrees. Positive is counterclockwise., opacity number -- From 0 invisible to 1 solid. Null: 1.);Fields:
| Name | Type | Description |
|---|---|---|
page |
pls_integer |
Page number from 1. Null: every page. |
document_id |
adm_documents.document_id%type |
The image document. Required. |
x |
number |
Required. Points from the left edge. |
y |
number |
Required. Points from the bottom edge. |
width |
number |
Width in points. More than 0. |
height |
number |
Height in points. More than 0. |
keep_aspect_ratio |
boolean |
With width and height: fit the image in the area. |
rotation |
number |
Angle in degrees. Positive is counterclockwise. |
opacity |
number |
From 0 invisible to 1 solid. Null: 1. |
t_image_overlays
Section titled “t_image_overlays”The images of add_image. Fill it with any index. The same image document can be in
more than one item.
Definition:
type t_image_overlays is table of t_image_overlay index by pls_integer;t_comment
Section titled “t_comment”One comment for add_comments. AOP makes a highlight annotation. A PDF viewer shows
the colored area, and shows the text when the user opens the note. x and y are the
lower left corner of the area, in points from the lower left corner of the page. Some
viewers draw the area solid and some draw it see-through, so use a light color.
Definition:
type t_comment is record ( page pls_integer -- Page number from 1. Null: every page., text varchar2(4000 char) -- The text of the note. Required. Up to 2000 characters., x number -- Required. Points from the left edge., y number -- Required. Points from the bottom edge., color varchar2(100 char) -- Hexadecimal color of the area. For example #ffff00., width number -- Width of the area. More than 0. Default of AOP: 200., height number -- Height of the area. More than 0. Default of AOP: 50.);Fields:
| Name | Type | Description |
|---|---|---|
page |
pls_integer |
Page number from 1. Null: every page. |
text |
varchar2(4000 char) |
The text of the note. Required. Up to 2000 characters. |
x |
number |
Required. Points from the left edge. |
y |
number |
Required. Points from the bottom edge. |
color |
varchar2(100 char) |
Hexadecimal color of the area. For example #ffff00. |
width |
number |
Width of the area. More than 0. Default of AOP: 200. |
height |
number |
Height of the area. More than 0. Default of AOP: 50. |
t_comments
Section titled “t_comments”The comments of add_comments. Fill it with any index.
Definition:
type t_comments is table of t_comment index by pls_integer;t_form_field
Section titled “t_form_field”One form field of a PDF, as get_form_fields returns it.
The values by type:
field_type |
What it is | value |
checked |
options |
|---|---|---|---|---|
string |
A text field | The text. Null when the field is empty. | Null | Null |
boolean |
A check box | Null | True or false | Null |
radio |
A group of radio buttons | The selected option. Null when none is selected. | Null | The options |
select |
A drop-down list or a list box | The selected option. Null when none is selected. | Null | The options |
signature |
A signature field | Null | Null | Null |
field_type is the text that AOP uses. A type that is not in the table has a value
when AOP gives a text for it. A list box with more than one selected option has the
options in value, separated by a line feed. pages holds the page number of every
widget of the field, so a radio group with two buttons on page 1 has 1, 1. A name
that belongs to more than one field has one entry for each.
Definition:
type t_form_field is record ( name varchar2(4000 char) -- The name of the field. Use it in t_form_value., field_type varchar2(100 char) -- string, boolean, radio, select, signature or another type of AOP, value varchar2(4000 char) -- The current value as text, checked boolean -- The state of a check box, options apex_t_varchar2 -- The options of a radio group or a list, pages apex_t_number -- The pages of the widgets);Fields:
| Name | Type | Description |
|---|---|---|
name |
varchar2(4000 char) |
The name of the field. Use it in t_form_value. |
field_type |
varchar2(100 char) |
string |
signature |
or another type of AOP |
- |
value |
varchar2(4000 char) |
The current value as text |
checked |
boolean |
The state of a check box |
options |
apex_t_varchar2 |
The options of a radio group or a list |
pages |
apex_t_number |
The pages of the widgets |
t_form_fields
Section titled “t_form_fields”The fields of get_form_fields, in the order of the PDF. A PDF without a form gives an
empty collection. The index starts at 1.
Definition:
type t_form_fields is table of t_form_field index by pls_integer;t_form_value
Section titled “t_form_value”One value for fill_form. Fill the field that has this name, as get_form_fields
returns it. What to set depends on the type of the field:
field_type |
Set | Remark |
|---|---|---|
string |
value |
Null makes the field empty. A text can have line breaks. |
boolean |
checked |
Do not set value. |
radio |
value |
The name of an option. Null is not allowed. |
select |
value |
The name of an option. Null is not allowed. |
fill_form checks all of this before it sends the file to AOP, because AOP does not.
AOP ignores a name that the PDF does not have. It writes an option that the list does not
have, and it turns any text into a checked check box.
The name can be longer than c_max_form_name_length and the value can be longer than
c_max_form_value_length in the record, so that a value that is too long raises
adm_error.e_invalid_param with a clear message and not an error of the PL/SQL
assignment.
Definition:
type t_form_value is record ( name varchar2(4000 char) -- The name of the field. Required., value varchar2(32767 char) -- The text, or the name of the option, checked boolean -- The state of a check box);Fields:
| Name | Type | Description |
|---|---|---|
name |
varchar2(4000 char) |
The name of the field. Required. |
value |
varchar2(32767 char) |
The text |
or |
the name of the option |
- |
checked |
boolean |
The state of a check box |
t_form_values
Section titled “t_form_values”The values of fill_form. Fill it with any index, for example
l_values(1).name := 'First Name';. The order does not matter. A name can be in it once.
Definition:
type t_form_values is table of t_form_value index by pls_integer;t_validation
Section titled “t_validation”The answer of validate.
valid is true when AOP can open the PDF and read its page tree. It is false when AOP
cannot. It is null when ADM cannot tell, which happens for a PDF that is protected with
a password: ADM does not send such a file to AOP. In that case encrypted is true.
message is the text of AOP for a file that is not valid, or a text of ADM for an empty
file, a file that is not a PDF or a file that is protected with a password. It is PDF is valid for a good file.
Definition:
type t_validation is record ( valid boolean, encrypted boolean, message varchar2(4000 char));Fields:
| Name | Type | Description |
|---|---|---|
valid |
boolean |
- |
encrypted |
boolean |
- |
message |
varchar2(4000 char) |
- |
t_signature_info
Section titled “t_signature_info”The result of the check of one digital signature, as verify_signatures returns it.
| Member | Value |
|---|---|
kind |
SIGNATURE, or TIMESTAMP for a document time stamp. A time stamp is listed and not checked: digest_ok and signature_ok are null. |
field_name |
The name of the signature field. Null when ADM does not find it, for example when the field is in an object stream. |
signer_dn |
The subject of the certificate in the signature, in the order of RFC 2253: the last part of the name in the certificate comes first, for example C=AT,O=Acme,CN=Ada Lovelace. |
signing_time |
The time that the signer claims. The signer sets it, and nothing proves it, unless the signature has a time stamp. |
digest_algorithm, signature_algorithm |
For example SHA-256 and RSA. |
covers_whole_file |
True when the signed bytes end at the end of the file. False when the file has more bytes behind the signature, for example the later signature of a second signer, or a change that was added after the signing. |
digest_ok |
True when the digest of the signed bytes is the digest in the signature. False means that the signed bytes changed. |
signature_ok |
True when the signature of the signed attributes is valid for the public key of the certificate in the signature. |
has_timestamp |
True when the signature holds a time stamp token (RFC 3161). ADM does not check the token. |
certificate_fingerprint |
SHA-256 of the certificate of the signer, in upper case hex. |
certificate_valid_from, certificate_valid_to |
The validity of the certificate. ADM does not compare it with the signing time. |
signing_key_id, signing_key_name |
The signing key of ADM that has this certificate. Null when no registered key has it. |
problem |
The text of a problem: the signature cannot be read, uses something that ADM does not support, or one of the checks failed. Null when all is well. |
A boolean is null when ADM could not make the check. problem then says why.
Definition:
type t_signature_info is record ( kind varchar2(10 char), field_name varchar2(500 char), signer_dn varchar2(1000 char), signing_time timestamp with time zone, digest_algorithm varchar2(20 char), signature_algorithm varchar2(30 char), covers_whole_file boolean, digest_ok boolean, signature_ok boolean, has_timestamp boolean, certificate_fingerprint varchar2(64 char), certificate_valid_from timestamp with time zone, certificate_valid_to timestamp with time zone, signing_key_id number, signing_key_name varchar2(255 char), problem varchar2(1000 char));Fields:
| Name | Type | Description |
|---|---|---|
kind |
varchar2(10 char) |
- |
field_name |
varchar2(500 char) |
- |
signer_dn |
varchar2(1000 char) |
- |
signing_time |
timestamp with time zone |
- |
digest_algorithm |
varchar2(20 char) |
- |
signature_algorithm |
varchar2(30 char) |
- |
covers_whole_file |
boolean |
- |
digest_ok |
boolean |
- |
signature_ok |
boolean |
- |
has_timestamp |
boolean |
- |
certificate_fingerprint |
varchar2(64 char) |
- |
certificate_valid_from |
timestamp with time zone |
- |
certificate_valid_to |
timestamp with time zone |
- |
signing_key_id |
number |
- |
signing_key_name |
varchar2(255 char) |
- |
problem |
varchar2(1000 char) |
- |
t_signature_infos
Section titled “t_signature_infos”The signatures of verify_signatures, in the order of the file. The index starts at 1.
Definition:
type t_signature_infos is table of t_signature_info index by pls_integer;Functions and Procedures
Section titled “Functions and Procedures”get_page_count
Section titled “get_page_count”The number of pages of a PDF document.
Raises adm_error.e_pdf_encrypted for a PDF that is protected with a password. Use
get_info to find out whether a PDF is protected without an error.
Signature:
function get_page_count ( p_document_id in adm_documents.document_id%type) return pls_integer;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
Returns: pls_integer - The number of pages
get_info
Section titled “get_info”Information about a PDF document, as JSON:
{ "documentId": 1234, "encrypted": false, "signed": false, "signatures": 0, "pageCount": 3, "metadata": { "documentInfo": { }, "technicalInfo": { } }}signatures is the number of digital signatures in the PDF, and signed is true when it
is more than 0. ADM finds them in the bytes of the file: a signature is an entry
/ByteRange with the four numbers of the signed ranges, and a /Contents that holds
the signature. A signature field that nobody signed yet is not counted. A document
time stamp is counted, because a change breaks it in the same way. The number does not
say that a signature is valid. It is also given for a PDF that is protected with a
password.
metadata is the metadata that AOP reads from the PDF, for example the title, the author
and the PDF version. A PDF that is protected with a password cannot be read by AOP. For
such a PDF the call does not raise an error. It returns "encrypted": true, and
pageCount and metadata are null.
Signature:
function get_info ( p_document_id in adm_documents.document_id%type) return clob;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
Returns: clob - The information as JSON text
validate
Section titled “validate”Checks the structure of a PDF document and says whether AOP can read it. It is meant as a diagnostic call: a file that is no good gives an answer and not an error.
- An empty file, or a file that does not start with
%PDF-(in its first 1024 bytes), givesvalidfalse and a message. The type of the document is not looked at. A document with the typetext/plainthat is a good PDF is valid. - A file that has a PDF header and that AOP cannot read, for example a file that ends
in the middle of the page tree, gives
validfalse and the message of AOP. - A PDF that is protected with a password gives
validnull andencryptedtrue. ADM does not send it to AOP. - AOP can rebuild a PDF that lost its end, so such a file is valid. A file is only not valid when AOP cannot find its pages.
The user needs view rights and, in an embed session, the grant DOWNLOAD, like for every
operation. The size of the file counts for PDF_MAX_FILE_SIZE_MB. A failure of AOP
itself, for example when the server is down, raises adm_error.e_pdf_operation_failed.
Signature:
function validate ( p_document_id in adm_documents.document_id%type) return t_validation;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The document |
Returns: t_validation - The answer, see t_validation
verify_signatures
Section titled “verify_signatures”Checks the digital signatures of a PDF document in the database and says what it found for every signature. A PDF without a signature gives an empty collection.
What the call checks, for every signature:
- The digest of the signed bytes is the digest in the signature (
digest_ok). - The signature is valid for the public key of the certificate in the signature
(
signature_ok), checked withDBMS_CRYPTO.VERIFY. - The signed bytes reach the end of the file (
covers_whole_file). - A registered signing key of ADM has this certificate (
signing_key_id).
What the call does not check. Do not read digest_ok and signature_ok as “this document is
signed by a person that you can trust”:
- Whether the certificate is trusted. ADM does not build a chain from the certificate to a root certificate, and it holds no list of roots. A self-signed certificate gives the same result as a certificate of a public authority.
- Whether the certificate was revoked. ADM does no OCSP request and reads no CRL.
- Whether the signing time is true.
signing_timeis what the signer claims. The time stamp token of a signature is not checked (has_timestampsays only that it is there). - Whether the signature conforms to PAdES, and whether the signed attributes are the ones that a profile asks for.
- Whether the file looks the same to a reader as it did when it was signed. A signature
with
covers_whole_filefalse leaves bytes behind it unsigned. The later signature of a second signer is such a case, and so is a change that an incremental update added.
Only RSA signatures are checked. For another algorithm, or when the signature cannot be
read, the entry has a problem and the checks that need it are null. The signature check
needs DBMS_CRYPTO.VERIFY. A database without it reports signature_ok null for every
signature.
The user needs view rights and, in an embed session, the grant DOWNLOAD, like for every
operation. The size of the file counts for PDF_MAX_FILE_SIZE_MB. The call does not use
AOP, and it reads a PDF that needs a password: the signature is not encrypted.
Signature:
function verify_signatures ( p_document_id in adm_documents.document_id%type) return t_signature_infos;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
Returns: t_signature_infos - One entry for every signature, see t_signature_info
get_provenance
Section titled “get_provenance”Where a version of a PDF document comes from. The status is set when ADM stores the version, and it is read from the database: the call does not read the file and does not use AOP.
| Status | Meaning |
|---|---|
NOT_SIGNED |
The PDF has no signature. |
ADM_SIGNED |
Every signature is of a signing key of ADM, every digest and signature is valid, and the last signature covers the whole file. |
MODIFIED |
A signature of a signing key of ADM is in the file and a check fails: the signed bytes changed, or the file has more bytes behind the last signature. |
FOREIGN_SIGNED |
The PDF has a signature of a certificate that is not a signing key of ADM, and no check of an ADM signature fails. |
UNKNOWN |
ADM cannot say: the PDF needs a password, or cannot be read, or a signature of an ADM key cannot be checked, or the version was stored before ADM kept the status and adm_pdf_provenance_api.backfill did not run yet. |
A certificate belongs to ADM when a signing key that is registered in ADM has it, in any
status. The status says nothing about the trust in the certificate, and nothing about the
time of the signature, see verify_signatures.
The user needs view rights on the document. The call needs no grant in an embed session: it returns one word and no content.
Signature:
function get_provenance ( p_document_id in adm_documents.document_id%type, p_version_id in adm_document_versions.version_id%type default null) return varchar2;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_version_id |
in | adm_document_versions.version_id%type default null |
The version. Null: the latest version. |
Returns: varchar2 - The status. Null when the document is not a PDF. adm_error.e_version_not_found when the version does not belong to the document.
get_provenance_summary
Section titled “get_provenance_summary”The status of the latest version of a PDF and of the version before it, as one line of text. The document info drawer (page 6) shows it.
| Status | Text |
|---|---|
NOT_SIGNED |
Not signed |
ADM_SIGNED |
Signed by ADM |
MODIFIED |
Signature of ADM, file changed afterwards |
FOREIGN_SIGNED |
Signed by someone else |
UNKNOWN |
Not checked |
The line is the text of the latest version. When the document has an older version, the
text of the version with the next lower version number follows in parentheses, for example
Signature of ADM, file changed afterwards (previous version: Signed by ADM). A version
without a status has the text of UNKNOWN, as in get_provenance.
The call reads two columns and does not read the file. The checks are the checks of
get_provenance: the user needs view rights on the document, and no grant in an embed
session.
Signature:
function get_provenance_summary ( p_document_id in adm_documents.document_id%type) return varchar2;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The document |
Returns: varchar2 - The line. Null when the document is not a PDF.
get_editor_signature_info
Section titled “get_editor_signature_info”What the built-in PDF editor must know about the signatures of a version before the user edits it, as a JSON object. The editor pages 10 and 13 read it when they open a PDF. A save in the editor writes a new file, so every signature of the version is lost.
| Member | Meaning |
|---|---|
provenance |
The status of the version, see get_provenance. When the stored status is empty or UNKNOWN, the status of a new check of the file. |
signingMode |
The signing mode of the folder of the document: OFF, WATCH or SIGN. Null when the setting AUTO_SIGN_DEFAULT_MODE holds a value that is not a mode. |
signatures |
The number of signatures in the file |
validSignatures |
The number of signatures with a valid digest and a valid signature |
canEdit |
True when the user has edit rights on the document |
removeSignatureWidgets |
True when the editor must delete the signature fields after the load: the version is ADM_SIGNED, the mode is SIGN, the user can edit and the file has less than two valid signatures. A save then gets a new ADM signature and keeps no old signature data. |
warning |
MULTI_SIGNED when the mode is SIGN and the file has two or more valid signatures: a save is refused with adm_error.e_auto_sign_multi_signed. SIGNATURE_LOST when the file has a signature that a save makes invalid. Null when there is nothing to tell. Only for a user who can edit. |
The call reads the file and checks its signatures. It does not use AOP. The user needs view rights on the document. The call needs no grant in an embed session: it returns numbers and no content.
Signature:
function get_editor_signature_info ( p_document_id in adm_documents.document_id%type, p_version_id in adm_document_versions.version_id%type default null) return varchar2;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The document |
p_version_id |
in | adm_document_versions.version_id%type default null |
The version that the editor shows. Null: the latest version. |
Returns: varchar2 - The JSON object. Null when the document is not a PDF. adm_error.e_version_not_found when the version does not belong to the document.
get_form_fields
Section titled “get_form_fields”The form fields of a PDF document: the name, the type, the current value, the options of
a radio group or a list, and the pages. A PDF without a form gives an empty collection.
Use the names with fill_form.
Raises adm_error.e_pdf_encrypted for a PDF that is protected with a password.
Signature:
function get_form_fields ( p_document_id in adm_documents.document_id%type) return t_form_fields;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
Returns: t_form_fields - The fields, see t_form_field
fill_form
Section titled “fill_form”Fills form fields of a PDF document and stores the result as a new PDF document. The fields that you do not name keep their values. The source document does not change.
ADM reads the fields of the PDF first (one more AOP call) and checks every value against
its field, see t_form_value. A name that the PDF does not have, a value of the wrong
kind, an option that the field does not have, a field that cannot be filled (a signature),
a name that is in the collection twice, and a value that is too long raise
adm_error.e_invalid_param. The message names the field and never the value. A
collection with more than c_max_form_values entries raises adm_error.e_limit_exceeded.
The values are not written to the log or to the audit entry.
The result still has its fields. Use flatten_form to turn them into fixed content.
Signature:
function fill_form ( p_document_id in adm_documents.document_id%type, p_values in t_form_values, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_values |
in | t_form_values |
The values, see t_form_value. At least one. |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (filled), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when the PDF has a digital signature. True: make the result anyway. fill_form appends to the file, so the old signature stays valid for the bytes that it signed, and it does not cover the whole file of the result. The audit entry says how many signatures the source had. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
flatten_form
Section titled “flatten_form”Flattens all form fields of a PDF document and stores the result as a new PDF document. The values that the fields show stay visible, but they are fixed content now: the fields are gone, and nobody can change the values. The signature fields are flattened too. A PDF without form fields gives an unchanged copy.
Signature:
function flatten_form ( p_document_id in adm_documents.document_id%type, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (flattened), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
get_attachments
Section titled “get_attachments”Takes the file attachments out of a PDF document. Every attachment becomes a new
document. The name of the document is the name of the attachment. The documents are in
the folder of the source document, unless you pass p_folder_id. The type of every
document is found from its content and its name.
A PDF without attachments is a normal case: the call returns an empty collection and
makes no document. AOP gives the same error for a PDF without attachments and for a file
that it cannot read. So when AOP finds no attachment, ADM asks AOP to validate the file
(one more call). A file that is not valid raises adm_error.e_pdf_operation_failed.
The names come from the PDF, and the author of the PDF chose them. ADM changes what
ADM does not allow in a document name: a path in front of the name is cut off, and
every character that is not allowed (/ \ < > " | ? *, control characters and
bidirectional overrides) becomes _. A name that is empty after this, or that has only dots, is attachment.
A name that is too long is cut in front of the extension. If two attachments end up
with the same name (case does not matter), the second one gets a number, scan (2).png.
If a name is used in the folder, see the section about the names of the results.
The call raises adm_error.e_limit_exceeded when the PDF has more than
c_max_attachments attachments, or when the files together are larger than
PDF_MAX_FILE_SIZE_MB. It makes no document then. An attachment is a file from an
unknown author. ADM stores it like any upload: the hooks of ADM run for every document.
Signature:
function get_attachments ( p_document_id in adm_documents.document_id%type, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true) return apex_t_number;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the documents. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
Returns: apex_t_number - The IDs of the new documents, in the order of the PDF. Empty when the PDF has no attachments.
add_attachments
Section titled “add_attachments”Puts documents into a PDF document as file attachments and stores the result as a new PDF document. The attachments are the paper clip of a PDF reader. The attachments that the PDF already has stay. The source documents do not change.
The user needs view rights on every attachment document, and in an embed session the
grant DOWNLOAD, like for a source PDF. The attachments can be of any type, but not
empty. Up to c_max_attachments documents. Their size counts for PDF_MAX_FILE_SIZE_MB
together with the PDF.
The name of an attachment in the PDF is the name of its document. Two attachments with the
same name (case does not matter) raise adm_error.e_invalid_param: AOP would keep only
one of them and say nothing. The same applies to a name that the PDF already uses for an
attachment, which ADM cannot see: AOP replaces the old attachment.
AOP refuses most types of file as the type of an attachment, for example
application/octet-stream and application/json. ADM gives AOP the type of the
document when AOP accepts it and text/plain otherwise. The name and the bytes of the
attachment stay as they are. Use get_attachments to take the files out again.
Signature:
function add_attachments ( p_document_id in adm_documents.document_id%type, p_attachment_ids in apex_t_number, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_attachment_ids |
in | apex_t_number |
The documents to attach. At least one. A document can be in it once. |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (attachments), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
Signs a PDF document with a signing key and stores the result as a new PDF document. The
source does not change. The signature is a PDF signature (adbe.pkcs7.detached, RSA with
SHA-256) that Adobe Reader, pdfsig and other readers show as a signature of the certificate
of the key.
How it works. AOP prepares the PDF with the public certificate and gives back the SHA-256
digest that has to be signed. ADM has the digest signed by the provider of the key (Transit,
OCI Vault, or the database), and AOP puts the signature into the PDF. The private key
never reaches AOP. AOP does not check the signature that it gets: it accepts bytes that are
not a signature. So ADM makes the check itself, with adm_pdf_signature_api.assert_new_signature,
before it stores anything. A result with a signature that is not valid is never stored
(adm_error.e_signature_invalid).
AOP 26.1.2 or newer is needed. With an older AOP the call raises adm_error.e_aop_too_old,
and the rest of ADM works as before.
What is checked before the content is read or sent, in this order: the call is not in an embed
session (adm_error.e_signing_not_in_embed), the key exists, the user holds a grant for
it, and the key is active with a certificate that is valid now (adm_error.e_signing_key_denied,
adm_error.e_signing_key_unusable). Then the rules of the other operations: view rights on the
source, edit rights on the target folder, a PDF (adm_error.e_not_a_pdf), the size limit
(adm_error.e_limit_exceeded), no password (adm_error.e_pdf_encrypted: AOP cannot sign a
PDF that needs a password). An administrator needs a grant too.
A source that is signed already is allowed. The new signature is added to the file and the
earlier signatures stay valid (an incremental update). That is how several signers sign
one document in turn. The result is checked for the new signature only. Call verify_signatures
on the result to see all of them.
The signature is invisible, unless p_field_name names a signature field of the PDF that is
not signed yet. The signature is then shown in the rectangle of that field, with the name of
the signer, the reason and the time. AOP raises an error for a name that is not such a field.
The time stamp: with p_timestamp true (the default) and the setting SIGNING_TSA_URL set,
the signature gets a time stamp token (RFC 3161) from that server. The setting is empty by
default, and then there is no token. p_timestamp => false never asks for one.
The audit trail gets one entry for the call. It names the key and its provider, the fingerprint of the certificate, the version of the source, the SHA-256 of the source and of the result, the digest that was signed and the time stamp server. It holds no key, no token and no signature.
The result is a new document, named like the source with (signed): contract.pdf gives
contract (signed).pdf, and a name that is taken gets a number, as for the other operations.
With p_overwrite the result is a new version of the document with that name. The hooks run for
the new document like for the other operations. A hook that changes the file makes the signature
invalid: use p_run_hooks => false (administrators only) or write hooks that leave PDFs alone,
and call verify_signatures when it matters.
Without an AOP URL the call raises adm_error.e_aop_not_configured. Another failure of AOP
raises adm_error.e_pdf_operation_failed, and a failure of the provider raises
adm_error.e_signing_failed. The text of the failure is in the log and not in the message.
Signature:
function sign ( p_document_id in adm_documents.document_id%type, p_signing_key_id in adm_signing_keys.signing_key_id%type, p_field_name in varchar2 default null, p_reason in varchar2 default null, p_location in varchar2 default null, p_contact_info in varchar2 default null, p_timestamp in boolean default true, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The document to sign |
p_signing_key_id |
in | adm_signing_keys.signing_key_id%type |
The key to sign with (adm_signing_keys.signing_key_id) |
p_field_name |
in | varchar2 default null |
The name of an unsigned signature field for a visible signature. Null: an invisible signature. |
p_reason |
in | varchar2 default null |
The reason, which PDF readers show. Up to 500 characters. Optional. |
p_location |
in | varchar2 default null |
The location, which PDF readers show. Up to 500 characters. Optional. |
p_contact_info |
in | varchar2 default null |
The contact of the signer, which PDF readers show. Up to 500 characters. Optional. |
p_timestamp |
in | boolean default true |
True: ask the time stamp server of the setting SIGNING_TSA_URL for a token, if there is one. False: no token. |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source with (signed). |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with the name. False: raise an error for a name that you passed, and use a number for a derived name. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new document. Only an administrator or the system user can pass false. |
Returns: adm_documents.document_id%type - The ID of the result document
convert_to_pdf
Section titled “convert_to_pdf”Converts a document to PDF and stores the result as a new PDF document. The source can
be a Word, Excel or PowerPoint file (.docx, .xlsx, .pptx), or a text, CSV, HTML
or Markdown file. The type is the MIME type of the document. A document of another
type raises adm_error.e_not_supported before its content is read. This includes a
PDF, and the older Office formats (.doc, .xls, .ppt), RTF, OpenDocument and
images. The source does not change.
The user needs view rights on the source, edit rights on the target folder, and in an
embed session the grants DOWNLOAD and UPLOAD (UPLOAD_VERSION with p_overwrite
on a PDF that exists), as for the other operations. They are checked before the
content is read. The size of the source is checked against the setting
PDF_MAX_FILE_SIZE_MB (adm_error.e_limit_exceeded).
An error is raised for each cause, and not hidden behind another one. A failure of AOP
raises adm_error.e_conversion_failed. AOP gives a file back unchanged when it cannot
convert it, so the call checks that the answer is a PDF and raises the same error when
it is not. Without an AOP URL the call raises adm_error.e_aop_not_configured.
The name: the name of the source with the extension replaced by .pdf, with a number
when the name is used. See the names of the results above.
Signature:
function convert_to_pdf ( p_document_id in adm_documents.document_id%type, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The document to convert |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source with .pdf, with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error for a name that you passed, and use a number for a derived name. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new document. Only an administrator or the system user can pass false. |
Returns: adm_documents.document_id%type - The ID of the result document
Joins PDF documents into one new PDF document. The pages are in the order of the collection. A document can be in the collection more than once.
The target folder is the folder of the first document, unless you pass p_folder_id.
Signature:
function merge ( p_document_ids in apex_t_number, p_folder_id in adm_folders.folder_id%type default null, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_ids |
in | apex_t_number |
The documents to join, in page order. At least 2 documents. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the first document. |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the first document plus (merged), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
Splits a PDF document into several new PDF documents.
With no option, every page becomes its own document. With p_pages_per_file every
document gets that number of pages (the last document gets what is left). With
p_split_by_text a new document starts at every page that holds the text. Use only one
of the two options.
A split can give only one file, for example for a PDF with one page. The call then makes one document. A split by text makes a document for the pages in front of the first page with the text, if the text first appears on a later page. When the text is on page 1, or on no page at all, the result is one document with all pages.
The names of the results are <name> (part 1).pdf, <name> (part 2).pdf and so on. If one
of these names is used in the folder, all results get the same number, for example
<name> (part 1) (2).pdf and <name> (part 2) (2).pdf. The documents are made in page
order. They are in the folder of the source document, unless you pass p_folder_id.
Signature:
function split ( p_document_id in adm_documents.document_id%type, p_pages_per_file in pls_integer default null, p_split_by_text in varchar2 default null, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return apex_t_number;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document to split |
p_pages_per_file |
in | pls_integer default null |
The number of pages of every result. Null: 1. |
p_split_by_text |
in | varchar2 default null |
Text that starts a new document. At most 500 characters. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the results. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: apex_t_number - The IDs of the new documents, in page order
watermark
Section titled “watermark”Puts a text on every page of a PDF document and stores the result as a new PDF document. Every option that you leave null has the default of AOP.
Signature:
function watermark ( p_document_id in adm_documents.document_id%type, p_text in varchar2, p_color in varchar2 default null, p_font in varchar2 default null, p_size in number default null, p_opacity in number default null, p_rotation in number default null, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_text |
in | varchar2 |
The text, up to 1000 characters |
p_color |
in | varchar2 default null |
The color as a hexadecimal value, for example #ff0000 |
p_font |
in | varchar2 default null |
The name of the font, up to 100 characters, for example Arial |
p_size |
in | number default null |
The size of the font in points. More than 0. |
p_opacity |
in | number default null |
A number from 0 (not visible) to 1 (solid) |
p_rotation |
in | number default null |
The angle of the text in degrees |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (watermarked), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
protect
Section titled “protect”Protects a PDF document with a password and stores the result as a new PDF document.
The new document is protected: it cannot be read by the other operations of this package
(see get_info). The source document does not change.
You must pass at least one of the two passwords. Without one, the call raises
adm_error.e_missing_param. The passwords are never written to the log, to the audit
log or to an error message. Do not store them in a place where others can read them.
Signature:
function protect ( p_document_id in adm_documents.document_id%type, p_read_password in varchar2 default null, p_modify_password in varchar2 default null, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_read_password |
in | varchar2 default null |
The password that is needed to open the result. Up to 200 characters. |
p_modify_password |
in | varchar2 default null |
The password that is needed to change the result. Up to 200 characters. |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (protected). |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No valid signature covers the whole file of the result. The audit entry says how many were invalidated. |
Returns: adm_documents.document_id%type - The ID of the result document
add_text
Section titled “add_text”Puts texts on the pages of a PDF document and stores the result as a new PDF document.
A text with page null is on every page. One call takes up to c_max_overlay_items
texts.
The call raises adm_error.e_invalid_param for a page that the PDF does not have. AOP
does not raise an error for it: it puts the text nowhere. A page number is checked with
one more AOP call, which the call makes only when a text has a page.
The texts are not written to the log or to the audit entry.
Signature:
function add_text ( p_document_id in adm_documents.document_id%type, p_texts in t_text_overlays, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_texts |
in | t_text_overlays |
The texts, see t_text_overlay. At least one. |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (text), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
add_image
Section titled “add_image”Puts images on the pages of a PDF document and stores the result as a new PDF document.
The images are PNG or JPEG documents of ADM, see t_image_overlay. The user needs view
rights on every image document. A document of another type raises
adm_error.e_not_supported, and a file that is not what its type says raises
adm_error.e_invalid_param. Both are checked before a file leaves the database.
One call takes up to c_max_overlay_items images. The size of the PDF and the size of
every image, once for every item, count for PDF_MAX_FILE_SIZE_MB. A page that the PDF
does not have raises adm_error.e_invalid_param, as for add_text.
Signature:
function add_image ( p_document_id in adm_documents.document_id%type, p_images in t_image_overlays, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_images |
in | t_image_overlays |
The images, see t_image_overlay. At least one. |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (image), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
add_comments
Section titled “add_comments”Puts comments on the pages of a PDF document and stores the result as a new PDF
document. A comment is a highlight annotation with a note, see t_comment. One call takes
up to c_max_overlay_items comments. A page that the PDF does not have raises
adm_error.e_invalid_param, as for add_text. The texts are not written to the log or
to the audit entry.
Signature:
function add_comments ( p_document_id in adm_documents.document_id%type, p_comments in t_comments, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_comments |
in | t_comments |
The comments, see t_comment. At least one. |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (comments), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
add_page_numbers
Section titled “add_page_numbers”Puts a page number on every page of a PDF document and stores the result as a new PDF document.
p_format is the text. ADM replaces {currentpage} with the number of the page and
{totalpage} with the number of pages of the PDF. The format needs {currentpage}.
With p_start_at the first page gets that number, and the numbers go up by 1. The
{totalpage} stays the number of pages of the PDF. For p_start_at => 5 and a PDF with
3 pages the texts of Page {currentpage} of {totalpage} are Page 5 of 3, Page 6 of 3
and Page 7 of 3.
The position comes from the size of every page, which the call reads from the PDF with one
more AOP call. A PDF can have pages of different sizes. Every page gets its own position.
The width of a text in the center and on the right is the width in Helvetica, and the
result is exact for Helvetica and Arial. Another font is wider or narrower. For Times New
Roman the text ends up to about 15 percent of its width in front of the margin. A page that has a
rotation in the PDF (the entry /Rotate) is treated as an upright page: the number is at
the edge of the unrotated page.
Signature:
function add_page_numbers ( p_document_id in adm_documents.document_id%type, p_format in varchar2 default 'Page {currentpage} of {totalpage}', p_position in varchar2 default c_position_bottom_center, p_start_at in pls_integer default 1, p_font in varchar2 default null, p_size in number default 10, p_color in varchar2 default null, p_margin in number default 36, p_document_name in adm_documents.document_name%type default null, p_overwrite in boolean default false, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true, p_invalidate_signatures in boolean default false) return adm_documents.document_id%type;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_format |
in | varchar2 default 'Page {currentpage} of {totalpage}' |
The text. Up to 1000 characters. Default Page {currentpage} of {totalpage}. |
p_position |
in | varchar2 default c_position_bottom_center |
One of the c_position_* values. Default bottom-center. |
p_start_at |
in | pls_integer default 1 |
The number of the first page. 0 or more. Default 1. |
p_font |
in | varchar2 default null |
The name of the font, up to 100 characters. Null: the default of AOP. |
p_size |
in | number default 10 |
The size of the font in points. More than 0. Default 10. |
p_color |
in | varchar2 default null |
The color as a hexadecimal value. Null: the default of AOP. |
p_margin |
in | number default 36 |
The distance to the edge of the page in points. Default 36 (half an inch). |
p_document_name |
in | adm_documents.document_name%type default null |
The name of the result. Null: the name of the source plus (numbered), with a number when the name is used. |
p_overwrite |
in | boolean default false |
True: add a new version to an existing PDF with this name. False: raise an error. |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the result. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
p_invalidate_signatures |
in | boolean default false |
False: raise adm_error.e_pdf_signed when a source PDF has a digital signature. True: make the result anyway. No signature of a source covers the whole file of the result. The audit entry says how many were invalidated. In a folder with the signing mode SIGN, a source that ADM signed needs no true, see Auto-sign in the description of the package. |
Returns: adm_documents.document_id%type - The ID of the result document
to_images
Section titled “to_images”Renders every page of a PDF document as an image. Every page becomes a new document of
the type image/jpeg. AOP can only make JPEG images.
The names of the results are <name> (page 1).jpg, <name> (page 2).jpg and so on. The
page numbers start at 1. If one of these names is used in the folder, all results get the
same number, for example <name> (page 1) (2).jpg. The documents are in the folder of the
source document, unless you pass p_folder_id.
Signature:
function to_images ( p_document_id in adm_documents.document_id%type, p_folder_id in adm_folders.folder_id%type default null, p_run_hooks in boolean default true) return apex_t_number;Parameters:
| Name | Direction | Type | Description |
|---|---|---|---|
p_document_id |
in | adm_documents.document_id%type |
The PDF document |
p_folder_id |
in | adm_folders.folder_id%type default null |
The folder for the images. Null: the folder of the source. |
p_run_hooks |
in | boolean default true |
False: no hooks run for the new documents. Only an administrator or the system user can pass false. |
Returns: apex_t_number - The IDs of the new documents, in page order