Tuesday, May 19, 2020

Oracle PL/SQL PART 1

Oracle PL/SQL Part 1

Overview

What is PL/SQL? PL/SQL is a database procedural language which can extend functionality of SQL. It gives to the developers ability to handle events from higher layers of application, executes procedures or functions and store the results in appropriate structures. Many organizations like banks, insurance company etc. uses that language. Some of them still uses old technology like i.e Oracle Forms which can execute also PL/SQL blocks of code.

Preliminary phase

Before we start exploring the PL/SQL functionality we have to prepare our environment.
The simplest way is to use docker image to run Oracle DB.  I found documentation on https://hub.docker.com/r/oracleinanutshell/oracle-xe-11g. Lets try to use that  image.

Lets run the image














Unlock the HR user
















Download SQLDeveloper and check connection

PL/SQL structure


 It is time to start. The structure of PL/SQL block should be similar to below structure.


Header - block of code could be anonymous or named. Anonymous block of code starts from key word "DECLARE" and it is not stored in DB's structures. Named block of code are i.e. functions, procedures, packages of code, triggers, etc.

Declaration section - this section contains definition of data types, structures and variables which could be used to assign references or store calculated values.

Execution section - this section is always required. It consists of execution code which cover business logic.

Exception section - this section is optional and it is appropriate place to handle errors and process them.


Basic anonymous block of code

Lets create simple block of code. I based on HR example schema. The block of code contains an anonymous cursor and loop. In the declaration section are defined variables: counter v_cnt and new table v_tab which base on new definition of type t_tab;    

SET SERVEROUTPUT ON
DECLARE 
    v_cnt PLS_INTEGER :=0;
 
    --declare new type - table of records
    TYPE t_tab IS TABLE OF departments.department_id%TYPE INDEX BY PLS_INTEGER;
 
    --create variable base on table type
    v_tab t_tab;
BEGIN
    DBMS_OUTPUT.PUT_LINE('START');
 
    --create anonymous cursor AND fill the table with records
    FOR dep IN (SELECT department_id FROM departments) LOOP
      v_tab(v_cnt) := dep.department_id;     
      v_cnt := v_cnt + 1;   
    END LOOP;
 
    --inerate over the table and show the departments
    FOR i in v_tab.FIRST .. v_tab.LAST LOOP
        DBMS_OUTPUT.PUT_LINE('DEPARTMENT_ID: '||v_tab(i));         
    END LOOP;
 
    DBMS_OUTPUT.PUT_LINE('STOP');
END;
/

BULK COLLECT

If there was a big number of record I could be used 'BULK COLLECT' statement to have better performance (there is no necessary to switch between SQL and PL/SQL engines so frequently like in cursor statements). Additionally there could be used also Limit statement for limiting returned number of rows - this prevents form consume all available memory in session.

SET SERVEROUTPUT ON
DECLARE     
    --declare new type - table of records
    TYPE t_tab IS TABLE OF departments.department_id%TYPE INDEX BY PLS_INTEGER;
 
    --create variable base on table type
    v_tab t_tab;
BEGIN
    DBMS_OUTPUT.PUT_LINE('START');
 
    --create 'select' statement with 'BULK COLLECT' phrase
    SELECT department_id
    BULK COLLECT INTO v_tab 
    FROM departments;
 
    --inerate over the table and show the departments
    FOR i in v_tab.FIRST .. v_tab.LAST LOOP
        DBMS_OUTPUT.PUT_LINE('DEPARTMENT_ID: '||v_tab(i));         
    END LOOP;
 
    DBMS_OUTPUT.PUT_LINE('STOP');
END;
/

FORALL LOOP

Similar to previous example we can increase performance with updating big number of rows without switching context between SQL and PL/SQL engines. I used additionally SAVEPOINT statement to control how changes will be propagate to persistent layer. 


SET SERVEROUTPUT ON
DECLARE     
    --declare new type - table of records
    TYPE t_tab IS TABLE OF departments.department_id%TYPE INDEX BY PLS_INTEGER;
 
    --create variable base on table type
    v_tab t_tab;
BEGIN
    SAVEPOINT s_dep;
    DBMS_OUTPUT.PUT_LINE('START');
 
    --create 'select' statement with 'BULK COLLECT' phrase
    SELECT department_id
    BULK COLLECT INTO v_tab 
    FROM departments;
 
 
    --update all select attributes in one statement
    FORALL j IN v_tab.FIRST..v_tab.LAST
        UPDATE departments SET department_name = department_name || '(OLD)'
        WHERE department_id = v_tab(j);
 
    --rollback all changes 
    ROLLBACK TO s_dep; 
         
    DBMS_OUTPUT.PUT_LINE('STOP');
END;
/  


CURSORS LOOP

In this example I created named cursor c_cur.  Before fetching rows is necessary to open cursor and after processing is necessary to close this cursor. There are many attributes on cursors:
  • FOUND
  • NOTFOUND
  • ISOPEN
  • ROWCOUNT

SET SERVEROUTPUT ON
DECLARE     
    --declare cursor
    CURSOR c_cur is
        SELECT department_id, department_name
        FROM departments;
 
    --declare row base on cursor
    r_rec c_cur%ROWTYPE;
BEGIN
    DBMS_OUTPUT.PUT_LINE('START');
 
    --open cursor
    OPEN c_cur;
 
    --fetch and process each row from cursor
    LOOP
        FETCH c_cur INTO r_rec;
        EXIT WHEN c_cur%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('DEP_ID:'||r_rec.department_id||' DEP_NAME:'||r_rec.department_name);
    END LOOP;
 
    --close cursor
    CLOSE c_cur;
         
    DBMS_OUTPUT.PUT_LINE('STOP');
END;
/



EXCEPTIONS

Resilient and exception handling is very important in block of code because if something goes wrong It  would be captured and fixed. In addition that type of event should be logged. Below is simple definition of few errors in the Exception section. Pre-defined exceptions are described in many pages i.e. https://docs.oracle.com/cd/B10501_01/appdev.920/a96624/07_errs.htm

SET SERVEROUTPUT ON
DECLARE     
    v_dep_id departments.department_id%TYPE;
BEGIN
    DBMS_OUTPUT.PUT_LINE('START');
 
    SELECT department_id INTO v_dep_id   
    FROM departments;
         
    DBMS_OUTPUT.PUT_LINE('STOP');
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE('NO_DATA_FOUND:'||SQLCODE||'; '||SQLERRM);
    WHEN TOO_MANY_ROWS THEN
        DBMS_OUTPUT.PUT_LINE('TOO_MANY_ROWS:'||SQLCODE||'; '||SQLERRM);
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('ERROR:'||SQLCODE||'; '||SQLERRM);         
END;
/

It is possible to define your own simple Exception e_my_own . In addition it is possible to assign error number by using  PRAGMA EXCEPTION_INIT.

SET SERVEROUTPUT ON
DECLARE     
    v_dep_id departments.department_id%TYPE; 
    e_my_own EXCEPTION;
    PRAGMA EXCEPTION_INIT(e_my_own,-777);
BEGIN
    DBMS_OUTPUT.PUT_LINE('START');
 
    SELECT department_id INTO v_dep_id   
    FROM departments where department_id = 10;
 
    RAISE e_my_own;
         
    DBMS_OUTPUT.PUT_LINE('STOP');
EXCEPTION
    WHEN e_my_own THEN
        DBMS_OUTPUT.PUT_LINE('e_my_own:'||SQLCODE||'; '||SQLERRM); 
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('ERROR:'||SQLCODE||'; '||SQLERRM);         
END;
/


WHAT ELSE

In next part I describe Types, procedures, objects, anonymous transactions and cache in functions etc.




Friday, May 8, 2020

How to configure Solr Index Sharding in Alfresco

How to configure Solr Index Sharding in Alfresco 

Objectives 

Solr is used as search engine in Alfresco. Overview concept is describe here: solr-overview.html. There are two cores:


  • alfresco - used for searching all live content
  • archive - used for searching content that has been marked as deleted

So, when there is too much documents stored in Alfresco i.e. over 100 million of documents, then one instance of Solr could works slowly. There is a few possibility to change Alfresco architecture to increase performance:
  • Enterprise
  • Enterprise - scaled
  • Replicated Index
  • Shared Index

All types of architecture is described in document:

I'm going to use my previous post "Alfresco new-project" as a base to this post and build Shared Index architecture.

For simplification I've changed approach to selected architecture - I focus on Solr but web layer and DB layer are designed in my example without replication and failover. I have only Alfresco Content Repository and only One Alfresco Share.





The most important thing is how does it work? Usually one request is executed in one core. Big Lucene query can be executed very long time. If we use index shards the query will be executed in defined numbers of separated processes across the Nodes. 

Finally you can read more about "Creating Solr shards" here: https://docs.alfresco.com/search-community/tasks/solr-hash-shard.html


The definition of Index Shards

At the end I would like to have 4 Nodes, 8 index shards, 3 replicas of each index shard. So, definition of index shards should be similar to below table:


Node 1
Node 2
Node 3
Node 4
0
1
0
0
1
2
2
1
2
3
3
3
4
5
4
4
5
6
6
5
6
7
7
7
  


Lets start

 At the beginning download Alfresco Search Services - Solr 6 (https://download.alfresco.com/cloudfront/release/community/201806-GA-build-00113/alfresco-search-services-1.1.1.zip)  

Then unzip archive and copy them to the four separate folders












Go to each Solr and run the instance:
·         Solr start -p 8091
·         Solr start -p 8092
·         Solr start -p 8093
·         Solr start -p 8094



Next call the configuration using URL requests:






Each request should present response similar to below output:


The default index sharding method is DB_ID. You can read more about available methods here: https://docs.alfresco.com/6.0/concepts/solr-shard-approaches.html 
It is necessary to check Solrcore.properties  






Next step is to switch to Alfresco application and configure 
alfresco-global.properties to use previously created Solr Nodes















The results

It is necessary to test our new configuration. Lets add a few new documents to Alfresco using Share





























Lets examine our indexes in Solr


















































There are created cores and indexes. 
 
So, everything works as we want to :)

Thursday, May 7, 2020

Alfresco - new project

Alfresco - new project

Objectives

Alfresco is ECM (Enterprise Content Management) - the system to store, manage and care about documents in their full live cycle. I've prepared high level conceptual diagram but the I won't describe the details because there are exists a lot of pages like i.e. https://docs.alfresco.com/6.1/concepts/welcome.html or Jeff Potts blog https://ecmarchitect.com/

     


The main goal is to create new project - add data model with fields, new forms to visualize new attributes and new search form


Lets start

I based on Jeff's tutorial and I prepared my own functionality. I added below prepared screens:

  • Search Form:
  


  • Edit form:




  • Attributes panel:



Preparation of the functionality

At the beginning you have to use Alfresco SDK and create new project from archtype:
https://docs.alfresco.com/5.1/tasks/alfresco-sdk-tutorials-all-in-one-archetype.html


I added my own model like below (content-model.xml):

















If you create new model you have to register it in bootstrap-context.xml:














It is necessary to register new forms and fields in share-config-custom.xml:






















Last element is very important. It is necessary to cast object to previously created model and create new rule.












That's all! :)

Saturday, December 29, 2018

Security - Ciphers


Introduction


Today I'm going to briefly present you a topic witch points to part of security - the ciphers. At the beginning I'll show you main classification of the ciphers and next in separately chapters will describe each kind of.





As You can see there is three main type of ciphers:

  1. Simple
  2. Asymmetric
  3. Symmetric

 Simple ciphers

Substitution ciphers generally replace each character with other one or some groups of charactes are replaced with other characrer or groups of characters. Depending of compexity and advanced of ciphers one character could be replaced by single character or character wich belongs to defined list of elements.

Transposition ciphers based on changing position of the characters. There could be build appropriate matrix where number of columns could depend on secret key. Changing the order of the columns generate unreadable text for the others.

Modern ciphers are mix of Substitution and Transposition ciphers. Lets see next categories.



Asymmetric ciphers

Asymmetric cryptography is kind of cryptography wich base on private and public key. One key is used to encrypt a message and the other key is used to decrypt the message. Is not possible to execute both operation encryption and decryption using one key. Usually is recommended to use public key for encryption so only owner of the private key can decrypt the message.
Encryption algorithm should be used with padding PKCS#1 or OEAP because of security.

The asymmetric algorithms:

  • RSA
  • Diffie–Hellman (one of the key-agreement algorithms)


Below is example of using RSA algorithm with OAEP padding. I use bouncycastle library (https://www.bouncycastle.org/)



package security;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

/**
 *
 * @author Artur
 */
public class AsyncCipher {
    private static final String incommingMessage = "message for encryption";
   
    public static void main(String[] args)
            throws InvalidKeyException, NoSuchAlgorithmException,
            IllegalBlockSizeException, BadPaddingException,
            NoSuchProviderException, NoSuchPaddingException {
       
        long startTime = System.currentTimeMillis();
        asyncCipher(incommingMessage);
        long endTime = System.currentTimeMillis();
        System.out.println("Execution time: " + ((endTime - startTime)) + " milliseconds");
    } 
   
    public static void asyncCipher(final String inMessage)
            throws InvalidKeyException, NoSuchAlgorithmException,
            IllegalBlockSizeException, BadPaddingException,
            NoSuchProviderException, NoSuchPaddingException {
       
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        byte[] message = inMessage.getBytes();
        Cipher rsaOaep = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");
        SecureRandom sr = new SecureRandom();
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");

        generator.initialize(2048, sr);

        KeyPair pair = generator.generateKeyPair();
        Key pubKey = pair.getPublic();
        Key privKey = pair.getPrivate();

        rsaOaep.init(Cipher.ENCRYPT_MODE, pubKey, sr);        
                    long startTime = System.currentTimeMillis();
                    byte[] encryptedMessage = rsaOaep.doFinal(message);
                    long endTime = System.currentTimeMillis(); 
                    System.out.println("Encryption Execution Time: " + ((endTime - startTime)) + " milliseconds; Encrypted                                message: ".concat(Base64.encodeBase64String(encryptedMessage)));

        rsaOaep.init(Cipher.DECRYPT_MODE, privKey);
        byte[] decryptedMessage = rsaOaep.doFinal(encryptedMessage);
        System.out.println("Decrypted message : ".concat(new String(decryptedMessage))); 
    }
}

Output:

Encryption Execution Time: 1 milliseconds; Encrypted message: Xby9krU99bBxdtr3ea+0tSlP0j7IySiysTmT4PTc/e2L6yIsulnagsrWYNRm59q1Vpt1fOZFJA/7IO+hwngY2ghWihhcGFRfrtPqzWp5Xc6afhg1u4iHO9RhOQc+s2Kfvg+4O7/+zNuCL4HTB4wkEdMS3qU4MPGtaD1o+MygsjPFJJoJZ/ZBn5wbIttjQGpE+Bp6ECQL70D9X8RGyYuuGvaPK9csP7ENMCCmtk0G0uPy7AKpe77A5xEOfUC9K68+af4XMHXeg+0PuhHVlsVSCG972cqlCz1vmKayumnDyzbK/eARrDL3xW54RqVAQlWQgeolcEHzapKcAc4qWuLf9Q==
Decrypted message : message for encryption
Execution time: 1584 milliseconds


I mentioned about key-agreement algorithms . This is base functionality used in SSL/TLS protocols.

Symmetric ciphers

Symmetric ciphers use the same key for encryption and decryption. There are two types of symmetric ciphers - stream and block ciphers. Below is attached diagram with the structure of symmetric ciphers.




Block ciphers split plain text in blocks which have the same size and next encrypt them one by one. Algorithm AES with CBC mode is able to mix data from different blocks. Stream ciphers work on stream of plaintext data and they do not divide it into smaller blocks.


Below is example of using AES algorithm with CBC mode. For authenticated encryption I recommend to use GCM mode.


package security;

import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.util.encoders.Hex;


/**
 *
 * @author Artur
 */
public class SyncCipher {
     private static final String incommingMessage = "message for encryption";
    
    public static void main(String[] args) 
            throws InvalidKeyException, NoSuchAlgorithmException, 
            IllegalBlockSizeException, BadPaddingException, 
            NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException {
        
        long startTime = System.currentTimeMillis();
        syncCipher(incommingMessage);
        long endTime = System.currentTimeMillis();
        System.out.println("Total Execution Time: " + ((endTime - startTime)) + " milliseconds");
    }  
    
    public static void syncCipher(final String inMessage) 
            throws InvalidKeyException, NoSuchAlgorithmException, 
            IllegalBlockSizeException, BadPaddingException, 
            NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException {
        
        java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        IvParameterSpec iv = new IvParameterSpec("myEncIntVector_1".getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec("myEncryptionKey1".getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        long startTime = System.currentTimeMillis();
        byte[] encryptedMessage = cipher.doFinal(inMessage.getBytes());  
        long endTime = System.currentTimeMillis();
        System.out.println("Encryption Execution Time: " + ((endTime - startTime)) + " milliseconds; Encrypted message: ".concat(Base64.encodeBase64String(encryptedMessage)));

        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] decryptedMessage = cipher.doFinal(encryptedMessage);
        System.out.println("Decrypted message : ".concat(new String(decryptedMessage)));  
    }
}


Encryption Execution Time: 0 milliseconds; Encrypted message: 5YWJup+o7SRd3o1rtqS1OtTCx7RpY8og8WDBZVXRNZM=
Decrypted message : message for encryption
Total Execution Time: 339 milliseconds


Tuesday, November 6, 2018

XML Schema

Objectives


Today I'm going to introduce you in subject of creating, visualization and using XSD. XML Schema was created by W3C for creating XML structure definition. This is a kind of contract which could be used in many solutions. One of the best usages is creating data model in WSDL (Web service contract)

Below is personal data's XSD structure which contains simple and complex types. There are diverse types of restrictions:

  • simple:  minOccurs, maxOccurs
  • complex: <xsd:restriction base="xsd:string"> 

There is also example of inheritance:  <xsd:extension base="as:document">

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:as="https://www.linkedin.com/in/artur-scigajlo-9144092/"
            targetNamespace="https://www.linkedin.com/in/artur-scigajlo-9144092/"
            xmlns:iso639-2="http://lcweb.loc.gov/standards/iso639-2/"
            elementFormDefault="qualified">
           
    <xsd:import namespace="http://lcweb.loc.gov/standards/iso639-2/"  schemaLocation="http://files.dnb.de/standards/xmetadiss/iso639-2.xsd"/>
               
               
   <xsd:complexType name="personalData">
        <xsd:sequence>
            <xsd:element name="workerId" type="xsd:string" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="worker" type="as:worker" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="partA" type="as:documentPartA" minOccurs="1" maxOccurs="unbounded"/>
            <xsd:element name="partB" type="as:documentPartB" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
             
  <xsd:complexType name="worker">
        <xsd:sequence>
            <xsd:element name="lastName" type="xsd:string" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="firstName" type="xsd:string" minOccurs="1" maxOccurs="1"/>
            <xsd:choice>
                <xsd:element name="personId">
                   <xsd:simpleType>
                    <xsd:restriction base="xsd:string">
                      <xsd:minLength value="10"/>
                      <xsd:maxLength value="26"/>
                    </xsd:restriction>
                  </xsd:simpleType>
                </xsd:element>
                <xsd:element name="otherTypeOfDocument">
                    <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="type" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                          <xsd:element name="number" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:choice>
        </xsd:sequence>
    </xsd:complexType>
   
        <xsd:complexType name="document">
            <xsd:sequence>
                <xsd:element name="documentId" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                <xsd:element name="title" type="as:title" minOccurs="0" maxOccurs="1"/>
                <xsd:element name="createdDate" type="xsd:date" minOccurs="1" maxOccurs="1"/>
                <xsd:element name="documentType" type="as:documentType" minOccurs="0" maxOccurs="1"/>
            </xsd:sequence>
    </xsd:complexType>
   
       <xsd:complexType name="title">
        <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="language" type="iso639-2:RegisteredCodeType" use="optional"/>
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>
   
      <xsd:complexType name="documentType">
        <xsd:sequence>
            <xsd:element name="type" minOccurs="1" maxOccurs="1">
              <xsd:simpleType>
                <xsd:restriction base="xsd:string">
                  <xsd:enumeration value="driverLicence"/>
                  <xsd:enumeration value="passport"/>
                  <xsd:enumeration value="insuranceNo"/>
                  <xsd:enumeration value="other"/>
                </xsd:restriction>
              </xsd:simpleType>
            </xsd:element>
            <xsd:element name="numer" type="xsd:string" minOccurs="1" maxOccurs="1"/>
        </xsd:sequence>
      </xsd:complexType>
   
    <xsd:complexType name="documentPartA">
        <xsd:complexContent>
            <xsd:extension base="as:document">
                <xsd:attribute name="subType" use="required">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                          <xsd:pattern value="^[ABC]\d{2}$"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
   
    <xsd:complexType name="documentPartB">
        <xsd:complexContent>
            <xsd:extension base="as:document">
                <xsd:attribute name="subType" use="required">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                          <xsd:pattern value="^[XYZ]\d{2}$"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>   

</xsd:schema>




Data model visualization

There are existing useful applications to help creating XSD. Some of them have a plugins to generate visualization diagrams. Below is our schema's diagram.





Genarating XML file base on XSD Schema


I created project in Netbeans.





I imported XSD and generated java classes automatically.







We can see the generated classes





The main class is used to generate XML file









Below is java class

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package artur.scigajlo;

import artur.scigajlo.personalData.DocumentPartA;
import artur.scigajlo.personalData.DocumentType;
import artur.scigajlo.personalData.PersonalData;
import artur.scigajlo.personalData.Title;
import artur.scigajlo.personalData.Worker;
import artur.scigajlo.personalData.Worker.OtherTypeOfDocument;
import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;

/**
 *
 * @author a.scigajlo
 */
public class PersonalDataProject {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws PropertyException, JAXBException {
              PersonalData ao = new PersonalData();
        ao.setWorkerId("worker_01");
     
        Worker worker = new Worker();
        worker.setFirstName("Jon");
        worker.setLastName("Black");
     
        OtherTypeOfDocument otherDoc = new OtherTypeOfDocument();
        otherDoc.setNumber("AAA123456");
        otherDoc.setType("otherPersonId"); 
        worker.setOtherTypeOfDocument(otherDoc);     
     
        ao.setWorker(worker);
     
     
        DocumentPartA docA1 = new DocumentPartA();
        docA1.setCreatedDate(XMLGregorianCalendarImpl.createDate(2018,3,4,0));
        docA1.setDocumentId("docID-714");
     
        Title t1 = new Title();
        t1.setLanguage("pol");
        t1.setValue("hello.pdf");
        docA1.setTitle(t1);
     
        DocumentType dt1 = new DocumentType();
        dt1.setNumer("AEC12");
        dt1.setType("driverLicence");
        docA1.setDocumentType(dt1);
     
        ao.getPartA().add(docA1);
     
        DocumentPartA docA2 = new DocumentPartA();
        docA2.setCreatedDate(XMLGregorianCalendarImpl.createDate(2018,5,14,0));
        docA2.setDocumentId("annexID-318");
     
        Title t2 = new Title();
        t2.setLanguage("pol");
        t2.setValue("test.pdf");
        docA2.setTitle(t2);
     
        DocumentType dt2 = new DocumentType();
        dt2.setNumer("AEC12");
        dt2.setType("driverLicence");
        docA2.setDocumentType(dt2);
     
        ao.getPartA().add(docA2);
         
        JAXBContext jaxbContext = JAXBContext.newInstance(PersonalData.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
     
     
        //ZAPIS DO PLIKU
        jaxbMarshaller.marshal(ao, new File("c:\\tmp\\PersonalData.xml"));
    }
 
}


Finally we get XML file