Saturday, March 23, 2013

ADF - Upload Download Functionality

First of all, create a table where the user will be uploading the documents
create table DOCUMENTS
(
  DOCUMENT_ID   NUMBER not null,
  ISSUE_ID      NUMBER,
  DOCUMENT_NAME VARCHAR2(100),
  DOCUMENT_TYPE VARCHAR2(100),
  DOCUMENT_FILE BLOB
)

alter table DOCUMENTS
  add constraint DOCUMENTS_PK primary key (DOCUMENT_ID);

Drop an inputFile component. Bind it with 'inputFile' variable of type RichInputFile. Bind its ValueChangeListener property with onFileUploadVCL method.
    public void onFileUploadVCL(ValueChangeEvent valueChangeEvent) {
        // Add event code here...
        file = (UploadedFile)valueChangeEvent.getNewValue();
        // Get the file name
        fileName = file.getFilename();
        // get the mime type
        contentType = file.getContentType();
        // get blob
        blob = getBlob(file);
    }

    public BlobDomain getBlob(UploadedFile file) {
        InputStream in = null;
        BlobDomain blobDomain = null;
        OutputStream out = null;
        try {
            in = file.getInputStream();
            blobDomain = new BlobDomain();
            out = blobDomain.getBinaryOutputStream();
            IOUtils.copy(in, out);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.fillInStackTrace();
        }
        return blobDomain;
    }

Create 4 variables like this below. Create getter setters for all these variables.
    private String fileName;
    private String contentType;
    private BlobDomain blob;

    private UploadedFile file;

Now drop a button and name it as 'Upload'. Bind this method with this button:
    public void onFileUpload(ActionEvent actionEvent) {
        // Add event code here...

        if (fileName != null) {
            DCBindingContainer bc =
                (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            OperationBinding operationbinding =
                bc.getOperationBinding("uploadFiletoDB");
            if (operationbinding != null) {
                operationbinding.getParamsMap().put("fileName", fileName);
                operationbinding.getParamsMap().put("contentType",
                                                    contentType);
                operationbinding.getParamsMap().put("blob", blob);
                operationbinding.execute();
            }
            System.out.println("File uploaded successfully");
            if (inputFile != null) {
                inputFile.resetValue();
                inputFile.setValid(true);
            }
        }
    }

This is the method defined in AM:
    public void uploadFiletoDB(String fileName, String contentType,
                               BlobDomain blob) {
        ViewObjectImpl vo = this.getDocumentsView1();
        try {
            Row row = vo.createRow();
            row.setAttribute("DocumentName", fileName);
            row.setAttribute("DocumentType", contentType);
            row.setAttribute("DocumentFile", blob);
            vo.insertRow(row);
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.getDBTransaction().commit();
    }

In order to download the file uploaded, drop a fileDownloadActionListener component with the following properties. Also create attribute bindings for the same:
ContentType: #{bindings.DocumentType.inputValue}
FileName: #{bindings.DocumentName.inputValue}
Method: #{myBean.downloadFile}

    public void downloadFile(FacesContext facesContext,
                             OutputStream outputStream) {
        // Add event code here...
        DCBindingContainer bindings =
            (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
        DCIteratorBinding iteratorbinding =
            bindings.findIteratorBinding("DocumentsView1Iterator");
        BlobDomain blob =
            (BlobDomain)iteratorbinding.getCurrentRow().getAttribute("DocumentFile");
        try {
            IOUtils.copy(blob.getInputStream(), outputStream);
            blob.closeInputStream();
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

In order to set larger maximum file size setting, add following parameter into Context Initialization Parameters group of web.xml:
org.apache.myfaces.trinidad.UPLOAD_MAX_DISK_SPACE


This example sets maximum file upload size to 10485760 bytes, or 10MB

3 comments:

  1. Also make sure that you have created a sequence for the Document table

    CREATE SEQUENCE DOCUMENTID_S
    MINVALUE 1
    START WITH 1
    INCREMENT BY 1
    CACHE 20;

    (new oracle.jbo.server.SequenceImpl("HR.DOCUMENTID_S", adf.object.getDBTransaction())).getSequenceNumber()

    ReplyDelete
  2. hi, can you send this samples for me le171282[at]gmail.com

    ReplyDelete
  3. Hi Sonal,
    I implemented as you shown above..But It showing Errors as:

    Cannot convert org.apache.myfaces.trinidadinternal.config.upload.UploadedFiles$FixFilename@bb4830 of type class org.apache.myfaces.trinidadinternal.config.upload.UploadedFiles$FixFilename to class oracle.adf.view.rich.component.rich.input.RichInputFile

    ReplyDelete