5 Oracle Multimedia Java API Sample Application

This chapter describes the Oracle Multimedia Java API sample application. The Oracle Multimedia Java API sample application is a Java application that uses Oracle Multimedia Java classes to demonstrate how to upload, download, update, and delete Oracle Multimedia objects, including image, audio, and video. It also demonstrates how to extract attributes from media content, generate thumbnail images, and display media.

This chapter assumes the following:

  • You are familiar with developing Java applications using Oracle Multimedia Java classes.

  • You have installed and configured the Oracle Multimedia Java API sample application.

After installing the Oracle Database Examples media, the sample application files and README.txt file are located at:

<ORACLE_HOME>/ord/im/demo/java (on Linux and UNIX)

<ORACLE_HOME>\ord\im\demo\java (on Windows)

This chapter describes how to run the Oracle Multimedia Java API sample application. See Section 2.4.1 and the README.txt file for additional requirements and instructions on installing, configuring, compiling, and running this sample application.

This chapter includes these sections:

More Sample Applications

See these chapters for more sample applications:

Chapter 3 describes these Photo Album sample Web applications:

  • Oracle Multimedia PL/SQL Web Toolkit Photo Album application (Section 3.1)

  • Oracle Multimedia Java Servlet Photo Album application (Section 3.2)

  • Oracle Multimedia JSP Photo Album application (Section 3.3)

These Web applications use PL/SQL scripts, Java servlet files, and JSP files to demonstrate various ways to upload and retrieve media using Oracle Multimedia object types.

Chapter 4 describes the Oracle Multimedia Code Wizard sample application, a media upload and retrieval Web application for the PL/SQL Gateway.

5.1 Running the Oracle Multimedia Java API Sample Application

To use the Oracle Multimedia Java API sample application to retrieve, save, play, and delete multimedia data from the Oracle Database sample schemas, you must perform these steps:

  1. Install Oracle Database with Oracle Multimedia.

  2. Grant the appropriate permissions to the user who is connecting to the database.

  3. Compile and start the sample application.

  4. Log in and run the sample application.

The following section describes the Java class files, and shows code examples that demonstrate how to use Oracle Multimedia object types and methods and other Oracle objects in a Java application.

5.2 Description of the Oracle Multimedia Java API Sample Application

The Oracle Multimedia Java API sample application lets you retrieve multimedia data from the Oracle Database sample schemas, save to a file, play, and delete from the sample schema image, audio, video, and testimonial data using these Oracle Multimedia object types:

  • OrdImage

  • OrdAudio

  • OrdVideo

  • OrdDoc

This sample application uses the PRODUCT_INFORMATION table in the Order Entry (OE) sample schema, and the ONLINE_MEDIA table in the Product Media (PM) sample schema.

Note:

After installing Oracle Multimedia, if the OE and PM sample schemas do not exist, you must install them manually before compiling and running the sample application.

See Also:

Oracle Database Sample Schemas for more information about the OE and PM schemas

The Oracle Multimedia Java API sample application, when compiled, creates the class files shown in Table 5-1:

Table 5-1 Java Class Files in the Compiled Sample Application

Name Description

IMExample

Creates the sample application frame and maintains the only connection to the database. This class is the entry point of this sample application.

IMExampleFrame

Extends the JFrame class and displays the main frame.

IMLoginDialog

Extends the JDialog class, displays the login dialog box, and creates the connection to the database.

IMExampleQuery

Performs the SQL SELECT statement to retrieve rows of the OE.PRODUCT_INFORMATION table and displays the content of the table by product ID.

IMProductDialog

Extends the JDialog class, shows a dialog box to display detailed information for a particular product, including the product ID, product name, and product description. The IMProductDialog class also retrieves and displays the product photo, audio, video, and testimonial data within the appropriate panel. It supports retrieving, saving, deleting, and playing the media data. And, it allows for applying changes or rolling back changes to the media objects.

IMImagePanel

Extends the IMMediaPanel class, displays the product photo and its attributes: MIME type, image height, image width, and content length, and if it applies, generates and displays the thumbnail image and displays lists for reading and writing metadata.

IMAudioPanel

Extends the IMMediaPanel class and displays the product audio and its attributes: MIME type, duration of the audio, and content length.

IMVideoPanel

Extends the IMMediaPanel class and displays the product video and its attributes: MIME type, frame height, frame width, duration of the video, and content length.

IMDocPanel

Extends the IMMediaPanel class and displays the product testimonials and its attributes: MIME type and content length.

IMLoadFile

Loads a media stream (photo, video, audio, and testimonials), from a file to the PM.ONLINE_MEDIA table in the database, and if necessary, inserts a row and initializes the media objects, then updates the media data, sets the media attributes, and generates and updates the thumbnail image if loading a photo.

IMSaveFile

Saves a media stream from the database to a target file.

IMMediaPanel

Extends the JPanel class, lays out the common components for the photo, audio, video, and doc panel with load, save, delete, and play check boxes, initializes the MIME configuration file for each operating system that lists plug-in players and media and their associated MIME types, plays the data stream associated with the MIME type of the media, and enables users to specify their own player to play the media data stream.


The major flow among these class files is: IMExample to IMExampleFrame to IMLoginDialog (login) to IMExampleFrame.showDefaultTable( ) to IMExampleQuery to IMProductDialog to one group of classes (IMImagePanel, IMAudioPanel, IMVideoPanel, IMDocPanel), and finally to the last group of classes (IMLoadFile, IMSaveFile, IMMediaPanel).

Table 5-2 lists and describes the remaining Java class files in this sample application:

Table 5-2 Additional Java Class Files in the Sample Application

Name Description

IMUtil

Includes common utilities such as a method to generate and update thumbnail images, wrapper methods for each setProperties( ) method of each media object type to separate the exceptions caused by unrecognizable formats, and cleanup methods to close the following: resultSet, Statement, input stream and its reader, and output stream and its writer.

IMMIME

Loads and stores the mapping between plug-in players and the MIME type.

IMResultSetTableModel

Extends the AbstractTableModel class and controls the display of the OE.PRODUCT_INFORMATION table.

IMMessage

Displays various messages for the sample application and classifies the message level as error, warning, or suggestion.

IMMessageResource

Extends the java.util.ListResourceBundle class and contains the actual message text for all messages.

IMJOptionPane

Extends and puts into subclasses the JOptionPane class to add an accessible description message to the displayed dialog box.

IMGetMetadataDialog

Extends the JDialog class, and retrieves the metadata from an image into an XML document and then displays the XML document in a JTree form.

IMPutMetadataDialog

Extends the JDialog class, and constructs an XMP packet to write into an image from user inputs.

XMLTreeNode

Extends the DefaultMutableTreeNode class, and creates a tree representation of an XML node.

XMLTreeView

Extends the JPanel class, and displays an XML document as a tree.

IMFileChooser

Extends the JFileChooser class, and inherits from the JFileChooser class to add the button mnemonic and accessible description.

IMConstants

Describes the IMConstants interface, which contains all the constants for column names, media types, message types, and message dialog titles.

IMAttrTableModel

Extends and puts into subclasses the DefaultTableModel class to provide the table model for displaying media attributes, and overwrites the isCellEditable( ) method to make the cells uneditable.

FocusedJTextField

Extends and puts into subclasses the JTextField class and overwrites the isFocusTraversable( ) method to enable it to gain focus when it is set to uneditable.

FocusedJTextArea

Extends and puts into subclasses the JTextArea class and overwrites the isFocusTraversable( ) method to enable it to gain focus when it is set to uneditable; also overrides the isManagingFocus( ) method to force the JTextArea class not to handle a TAB key operation.

FocusedJPanel

Extends and puts into subclasses the JPanel class and overwrites the isFocusTraversable( ) method to enable it to gain focus.

FocusedJLabel

Extends and puts into subclasses the JLabel class, overwrites the isFocusTraversable( ) method, and adds a focus listener to enable it to gain focus.

BooleanRenderer

Extends the JCheckBox class and renders Boolean objects as JCheckBox (a check box) in a JTable (two-dimensional table format). This class also sets the AccessibleName and AccessibleDescription properties by setting the tooltip to support accessibility.

IMStreamAbsorber

Extends the Thread class and runs as a separate thread to consume an input stream. This is useful when a plug-in application is loaded and it writes something out to, for example, a standard error, without consuming the application's output, the application may be unable to continue.

IMTable

Extends and puts into subclasses the JTable class and overwrites the isManagingFocus( ) method to avoid letting the table handle a TAB key operation.

IMTableRenderer

Extends the DefaultTableCellRenderer class and renders the PRODUCT_ID, PRODUCT_NAME, and PRODUCT_DESCRIPTION columns to add accessibility information, and sets the customized display.

IMUIUtil

Includes common GUI utilities.


The following subsections describe the main operations that are performed within specific classes in the Oracle Multimedia Java API sample application:

5.2.1 Operations in the IMProductDialog Class

This class defines the following methods followed by a description of what each method does:

  • The loadMedia( ) method to retrieve the media objects from the database. This method performs a SQL SELECT...FOR UPDATE statement on the PM.ONLINE_MEDIA table where the PRODUCT_ID column is a parameter marker. Then, this class uses the getORAData( ) and getORADataFactory( ) methods to get the media data objects from the result set.

  • The displayMedia( ) method to display the media data, which in turn calls the corresponding media display methods displayImage( ), displayAudio( ), displayVideo( ), and displayDoc ( ).

  • The displayImage( ) method calls the IMImagePanel.display( ) method to display the image data attributes, display the thumbnail image, and display the full sized image using a media player that supports this MIME type.

  • The displayAudio( ) method calls the IMAudioPanel.display( ) method to display the audio data attributes and play the audio stream using a media player that supports this MIME type.

  • The displayVideo( ) method calls the IMVideoPanel.display( ) method to display the video data attributes and play the video stream using a media player that supports this MIME type.

  • The displayDoc( ) method calls the IMDocPanel.display( ) method to display the testimonial data attributes and play the testimonial data using a media player that supports this MIME type.

The following code example shows the loadMedia( ), displayMedia( ), displayImage( ), displayAudio( ), displayVideo( ), and displayDoc( ) methods, and highlights in bold the SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used.

  private void loadMedia() throws SQLException, IOException
  {
    String sQuery = 
      "select product_photo, product_thumbnail, product_audio, product_video, " + 
      "product_testimonials from pm.online_media where product_id = ? for update";

    OracleConnection conn = null;
    OracleResultSet rs = null;
    OraclePreparedStatement pstmt = null;
    boolean isInsertNeeded = false;
    byte[] ctx[] = new byte[1][64];

    try
    {
      conn = IMExample.getDBConnection();

      pstmt = (OraclePreparedStatement)conn.prepareStatement(sQuery);
      pstmt.setInt(1, m_iProdId);
      rs = (OracleResultSet)pstmt.executeQuery();
      if (rs.next() == true)
      {
        m_img = (OrdImage)rs.getORAData(1, OrdImage.getORADataFactory());
        m_imgThumb = (OrdImage)rs.getORAData(2, OrdImage.getORADataFactory());
        m_aud = (OrdAudio)rs.getORAData(3, OrdAudio.getORADataFactory());
        m_vid = (OrdVideo)rs.getORAData(4, OrdVideo.getORADataFactory());
        m_doc = (OrdDoc)rs.getORAData(5, OrdDoc.getORADataFactory());
      }

      displayMedia();

      rs.close();
      pstmt.close();
    }
    finally
    {
      IMUtil.cleanup(rs, pstmt);
    }
  }

  private void displayMedia() throws SQLException, IOException
  {
    displayImage();
    displayAudio();
    displayVideo();
    displayDoc();
  }

  /**   * Add the product photo panel.
   */
  private void displayImage() throws SQLException, IOException
  {
    m_jImgPanel = new IMImagePanel(this, 
        m_img, m_imgThumb, m_iProdId, m_colorFieldBg);
    m_jImgPanel.display();
    m_jImgPanel.getAccessibleContext().setAccessibleName
      ("Product photo panel");
    m_jImgPanel.getAccessibleContext().setAccessibleDescription
      ("Product photo panel with an image icon on the left, " + 
       "image attribute panel in the middle and image control" +
        "panel on the right.");

    m_jMediaPanel.add(m_jImgPanel);

    Component jImgFocus = m_jImgPanel.getFirstFocusComponent();
  }

  /**
   * Add the product audio panel.
   */
  private void displayAudio() throws SQLException, IOException
  {
    m_jAudPanel = new IMAudioPanel(this, m_aud, m_iProdId, m_colorFieldBg);
    m_jAudPanel.display();
    m_jAudPanel.getAccessibleContext().setAccessibleName
      ("Product audio panel");
    m_jAudPanel.getAccessibleContext().setAccessibleDescription(
        "Product audio panel with an audio icon at the left, " + 
        "audio attribute panel in the middle and audio control" +
        "panel at the right.");
    m_jMediaPanel.add(m_jAudPanel);
  }

  /**
   * Add the product video panel.
   */
  private void displayVideo() throws SQLException, IOException
  {
    m_jVidPanel = new IMVideoPanel(this, m_vid, m_iProdId, m_colorFieldBg); 
    m_jVidPanel.display();
    m_jVidPanel.getAccessibleContext().setAccessibleName
      ("Product audio panel");
    m_jVidPanel.getAccessibleContext().setAccessibleDescription(
        "Product audio panel with an video icon at the left, " + 
        "video attribute panel in the middle and video control" +
        "panel at the right.");
    m_jMediaPanel.add(m_jVidPanel);
  }

  /**
   * Add the product testimonials panel.
   */
  private void displayDoc() throws SQLException, IOException
  {
    m_jDocPanel = new IMDocPanel(this, m _doc, m_iProdId, m_colorFieldBg);
    m_jDocPanel.display();
    m_jDocPanel.getAccessibleContext().setAccessibleName
      ("Product testimonials panel");
    m_jDocPanel.getAccessibleContext().setAccessibleDescription(
        "Product testimonials panel with an document icon at the left, " + 
        "testimonials attribute panel in the middle and testimonials control" +
        "panel at the right.");
    m_jMediaPanel.add(m_jDocPanel);
  }

See the following sections, respectively, for code examples of the corresponding m_jXxxPanel.display( ) methods, where Xxx represents the particular media data type, Img, Aud, Vid, or Doc:

5.2.2 Operations in the IMImagePanel Class

This class displays the image panel, the product photo and its attributes, and the thumbnail image, and lists for reading and writing metadata. What follows is a more detailed description of each of the methods that are defined and what each method does:

  • The display( ) method, which first calls the insertProperty( ) method, which calls the Oracle Multimedia image object type methods getMimeType( ), getHeight( ), getWidth( ), and getContentlength( ) to get the attributes of the image to display in a table, and lays out the user interface components for reading and writing image metadata.

  • For supported formats, the class displays the product photo thumbnail image, which is generated by calling the IMUtil.generateThumbnail( )method to create the thumbnail image from the product photo.

  • The addThumbnail( ) method to show the new thumbnail image.

  • The changeThumbnail( ) method to change the thumbnail image.

  • The saveToFile( ) method to save the photo to a file.

  • The deleteMedia( ) method to delete the product photo image and its thumbnail image from the database by setting the image object type columns to empty using the OrdImage.init( ) method.

  • The play( ) media method to show the image using a media player.

  • The setMedia( ) method to set the photo and thumbnail object.

  • The notExist( ) method checks whether the image data exists and returns true if the BLOB is empty or is not associated with an existing BFILE; otherwise, it returns false.

  • The getDataInByteArray( ) method retrieves image data into a byte array by calling the Oracle Multimedia importData( ) method first for the BFILE and returns the results of calling the Oracle Multimedia getDataInByteArray( ) method.

  • The refreshPanel( ) method refreshes the display when updating the photo image, attributes, and thumbnail image.

  • The getFirstFocusComponent( ) method enforces the correct focus order.

  • The emptyPanel( ) method clears the icon and attribute panel.

  • The showMetadata( ) method to pop up a window for displaying metadata for the selected type.

  • The writeMetadata( ) method to display the write metadata dialog.

The following code example includes the display( ), insertProperty( ), notExist( ), getDataInByteArray( ), and refreshPanel( ) methods, and highlights in bold any SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used:

  void display() throws IOException, SQLException
  {
    addControlPane();

    if (notExist(m_img))
    {
      // The image does not exist.
      m_hasMedia = false; 
      layoutEmpty(s_sNotExist);
    }
    else
    {
      m_hasMedia = true; 
      // If image exists, try to show the attributes.
      if (insertProperty())
      {
        // Show the thumbnail image.
        // If the thumbnail image does not exist, generate it first.
        if (m_imgThumb != null)
        {
          String sFormat = m_imgThumb.getFormat();

          if (notExist(m_imgThumb) ||
              ( !("JFIF".equalsIgnoreCase(sFormat)) &&
                !("GIFF".equalsIgnoreCase(sFormat))
              ))
          {
            m_imgThumb = IMUtil.generateThumbnail(m_iProdId, m_img, m_imgThumb);
          }

          byte[] thumbnail = getDataInByteArray(m_imgThumb);
          addThumbnail(thumbnail);
        }
        else
        {
          m_imgThumb = IMUtil.generateThumbnail(m_iProdId, m_img, m_imgThumb);
          byte[] thumbnail = getDataInByteArray(m_imgThumb);
          addThumbnail(thumbnail);
        }
      }
    }
  }
.
.
.
  boolean insertProperty() throws SQLException
  {
    boolean isFormatSupported = false;
    String sMimeType = m_img.getMimeType();

    if (sMimeType == null)
      isFormatSupported = IMUtil.setProperties(m_img);
    else
      isFormatSupported = true;

    if (!isFormatSupported)
    {
      layoutEmpty(s_sNotSupported);
    }
    else
    {
      Object[][] data = 
      {
        {"MIME Type",  m_img.getMimeType()},
        {"Height", new Integer(m_img.getHeight()).toString()},
        {"Width",  new Integer(m_img.getWidth()).toString()},
        {"Content Length", new Integer(m_img.getContentLength()).toString()}
      };

      .
      .
      .
    }

    return isFormatSupported;  }
.
.
.
  static boolean notExist(OrdImage img) throws SQLException, IOException
  {
    if (img == null)
      return true;
    else
    {
      if (img.isLocal() && (img.getDataInByteArray() == null))
        return true;
      else if (!img.isLocal() && (":///".equals(img.getSource())))
        return true;
      else
      {
        if (!img.isLocal())
        {
          BFILE bfile = img.getBFILE();
          if (!bfile.fileExists())
            return true;
          else 
            return false;
        }
        else
          return false;
      }
    }
  }
.
.
.
  static byte[] getDataInByteArray(OrdImage img) throws SQLException, IOException
  {
    if (notExist(img))
      return null;
    else
    {
      if (!img.isLocal())
      {
        byte[] ctx[] = new byte[1][4000];
        try
        {
          img.importData(ctx);
        }
        catch (SQLException e)
        {
          new IMMessage(IMConstants.ERROR, "MEDIA_SOURCE_ERR", e);
          return null;
        }
      }
      return img.getDataInByteArray();
    }
  }
.
.
.
  void refreshPanel(boolean isFormatSupported) throws SQLException, IOException
  {
    m_hasMedia = true;
    if (isFormatSupported)
    {
      if (m_jAttrTbl == null)
      {
        m_jAttrPane.remove(m_jEmpty);
        m_jIconPane.remove(m_jIcon);

        byte[] thumbnail = getDataInByteArray(m_imgThumb);
        addThumbnail(thumbnail);

        insertProperty();
      }
      else
      {
        byte[] thumbnail = getDataInByteArray(m_imgThumb);
        changThumbnail(thumbnail);

        m_jAttrTbl.setValueAt(m_img.getMimeType(), 0, 1);
        m_jAttrTbl.setValueAt(new Integer(m_img.getHeight()).toString(), 1, 1);
        m_jAttrTbl.setValueAt(new Integer(m_img.getWidth()).toString(), 2, 1);
        m_jAttrTbl.setValueAt(new Integer(m_img.getContentLength()).toString(),3, 1);
      }
    }
   .
   .
   .
  }

5.2.3 Operations in the IMGetMetadataDialog Class

This class shows a dialog to display detailed information for metadata in a product photograph. This class also defines the displayMetadata( ) method and describes what it does.

The displayMetadata( ) method retrieves metadata from the image by using the Oracle Multimedia OrdImage getMetadata( ) method, and then displays the metadata.

The following code example includes the displayMetadata( ) method, and highlights in bold any SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used:

  private void displayMetadata(String sMetaType) 
  {
    XMLDocument doc = null;
    try
    {
      //
      // Retrieves the metadata into an XMLType array
      //
      XMLType xmlList[] = m_img.getMetadata(sMetaType);
 
      if (xmlList.length == 1)
      {
        DOMParser parser = new DOMParser();
        parser.setValidationMode(XMLConstants.NONVALIDATING);
        parser.setPreserveWhitespace(false);
        parser.parse(new StringReader(XMLType.createXML(xmlList[0]).getStringVal()));
        doc = parser.getDocument();
      }
    }
    .
    .
    .
  }

5.2.4 Operations in the IMPutMetadataDialog Class

This class shows a dialog to write metadata into a product photograph. This class also defines the writeMetadata( ) method and describes what it does.

The writeMetadata( ) method writes XMP metadata into the image metadata by using the Oracle Multimedia OrdImage putMetadata( ) method.

The following code example includes the writeMetadata( ) method, and highlights in bold any SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used:

  void writeMetadata()
  {
    try
    {
      //
      // Let the StringBuffer to hold the XMP packet
      //
      StringBuffer sb = new StringBuffer(
          "<xmpMetadata xmlns=\"http://xmlns.oracle.com/ord/meta/xmp\" "
          + " xsi:schemaLocation=\"http://xmlns.oracle.com/ord/meta/xmp "
          + " http://xmlns.oracle.com/ord/meta/xmp\" "
          + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" > "
          + " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"> "
          + " <rdf:Description about=\"\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"> "
          );
 
      String str = null;
      if ( (str=m_jTitleField.getText()) != null)
        sb.append("<dc:title>" + str + "</dc:title>");
      if ( (str=m_jCreatorField.getText()) !=null)
        sb.append("<dc:creator>" + str + "</dc:creator>");
      if ( (str=m_jDateField.getText()) !=null)
        sb.append("<dc:date>" + str + "</dc:date>");
      if ( (str=m_jDescriptionField.getText()) !=null)
        sb.append("<dc:description>" + str + "</dc:description>");
      if ( (str=m_jCopyrightField.getText()) !=null)
        sb.append("<dc:rights>" + str + "</dc:rights>");
 
      sb.append("</rdf:Description></rdf:RDF></xmpMetadata>");
 
      XMLType xmp = XMLType.createXML(IMExample.getDBConnection(), sb.toString(),
                "http://xmlns.oracle.com/ord/meta/xmp", true, true);
 
      //
      // Make sure the image data is local
      //
      if (!m_img.isLocal())
      {
        byte[] ctx[] = new byte[1][4000];
        m_img.importData(ctx);
      }
 
      //
      // Call Ordimage.putMetadata
      //
      m_img.putMetadata(xmp, "XMP", "utf-8");
 
      this.dispose();
    }
    .
    .
    .
  }

5.2.5 Operations in the IMVideoPanel Class

This class displays the video panel, the product video, and its attributes. This class is identical in structure and functions similarly to the IMImagePanel class. See Operations in the IMImagePanel Class for descriptions of methods.

The following code example includes the display( ), insertProperty( ), notExist( ), getDataInByteArray( ), and refreshPanel( ) methods, and highlights in bold any SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used:

  void display() throws IOException, SQLException
  {
    addControlPane();

    // Set the video icon.
    m_jIcon = new JLabel(new ImageIcon(IMExampleFrame.class.getResource("OrdVideo.gif")));
    m_jIcon.setLabelFor(m_jAttrPane);

      m_jIconPane.add(m_jIcon, BorderLayout.CENTER);

    if (notExist())
    {
      // The video does not exist.
      m_hasMedia = false; 
      layoutEmpty(s_sNotExist);
    }
    else
    {
      m_hasMedia = true; 
      // If the video exists, try to show the attributes.
      insertProperty();
    }
  }
.
.
.
  boolean insertProperty() throws SQLException
  {
    boolean isFormatSupported = false;
    String sMimeType = m_vid.getMimeType();

    if (sMimeType == null)
      isFormatSupported = IMUtil.setProperties(m_vid);
    else
      isFormatSupported = true;

    if (!isFormatSupported)
    {
      layoutEmpty(s_sNotSupported);
    }
    else
    {
      Object[][] data = 
      {
        {"MIME Type",  m_vid.getMimeType()},
        {"Height", new Integer(m_vid.getHeight()).toString()},
        {"Width",  new Integer(m_vid.getWidth()).toString()},
        {"Duration", new Integer(m_vid.getVideoDuration()).toString()},
        {"Content Length", new Integer(m_vid.getContentLength()).toString()}
      };
      .
      .
      .
    }

    return isFormatSupported;  }
.
.
.
  boolean notExist() throws SQLException, IOException
  {
    if (m_vid == null)
      return true;
    else
    {
      if (m_vid.isLocal() && (m_vid.getDataInByteArray() == null))
        return true;
      else if (!m_vid.isLocal() && (":///".equals(m_vid.getSource())))
        return true;
      else
      {
        if (!m_vid.isLocal())
        {
          BFILE bfile = m_vid.getBFILE();
          if (!bfile.fileExists())
            return true;
          else 
            return false;
        }
        else
          return false;
      }
    }
  }
.
.
.
  byte[] getDataInByteArray(OrdVideo vid) throws SQLException, IOException
  {
    if (!m_hasMedia)
      return null;
    else
    {
      if (!vid.isLocal())
      {
        byte[] ctx[] = new byte[1][4000];
        try
        {
          vid.importData(ctx);
        }
        catch (SQLException e)
        {
          new IMMessage(IMConstants.ERROR, "MEDIA_SOURCE_ERR", e);
          return null;
        }
      }
      return vid.getDataInByteArray();
    }
  }
.
.
.
  void refreshPanel(boolean isFormatSupported) throws SQLException, IOException
  {
    m_hasMedia = true;

    if (isFormatSupported)
    {
      if (m_jAttrTbl == null)
      {
        m_jAttrPane.remove(m_jEmpty);
        insertProperty();
      }
      else
      {
        m_jAttrTbl.setValueAt(m_vid.getMimeType(), 0, 1);
        m_jAttrTbl.setValueAt(new Integer(m_vid.getHeight()).toString(), 1, 1);
        m_jAttrTbl.setValueAt(new Integer(m_vid.getWidth()).toString(), 2, 1);
        m_jAttrTbl.setValueAt(new Integer(m_vid.getVideoDuration()).toString(), 3, 1);
        m_jAttrTbl.setValueAt(new Integer(m_vid.getContentLength()).toString(), 4, 1);
      }
    }
        .
        .
        .
  }

5.2.6 Operations in the IMAudioPanel Class

This class displays the audio panel, the product audio, and its attributes. This class is identical in structure and functions similarly to the IMImagePanel class. See Operations in the IMImagePanel Class for descriptions of methods.

The following code example includes the display( ), insertProperty( ), notExist( ), getDataInByteArray( ), and refreshPanel( ) methods, and highlights in bold any SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used:

  void display() throws IOException, SQLException
  {
    addControlPane();

    // Set the audio icon.
    m_jIcon = new JLabel(new ImageIcon(IMExampleFrame.class.getResource("OrdAudio.gif")));
    m_jIcon.setLabelFor(m_jAttrPane);

      m_jIconPane.add(m_jIcon, BorderLayout.CENTER);

    if (notExist())
    {
      // The audio does not exist.
      m_hasMedia = false; 
      layoutEmpty(s_sNotExist);
    }
    else
    {
      m_hasMedia = true;

      // If the audio exists, try to show the attributes.
      insertProperty();
    }
  }
.
.
.
  boolean insertProperty() throws SQLException
  {
    boolean isFormatSupported = false;
    String sMimeType = m_aud.getMimeType();

    if (sMimeType == null)
      isFormatSupported = IMUtil.setProperties(m_aud);
    else
      isFormatSupported = true;

    if (!isFormatSupported)
    {
      layoutEmpty(s_sNotSupported);
    }
    else
    {
      Object[][] data = 
      {
        {"MIME Type",  m_aud.getMimeType()},
        {"Duration", new Integer(m_aud.getAudioDuration()).toString()},
        {"Content Length", new Integer(m_aud.getContentLength()).toString()}
      };

      .
      .
      .
    }

    return isFormatSupported;
  }
.
.
.
  boolean notExist() throws SQLException, IOException
  {
    if (m_aud == null)
      return true;
    else
    {
      if (m_aud.isLocal() && (m_aud.getDataInByteArray() == null))
        return true;
      else if (!m_aud.isLocal() && (":///".equals(m_aud.getSource())))
        return true;
      else
      {
        if (!m_aud.isLocal())
        {
          BFILE bfile = m_aud.getBFILE();
          if (!bfile.fileExists())
            return true;
          else 
            return false;
        }
        else
          return false;
      }
    }
  }
.
.
.
  byte[] getDataInByteArray(OrdAudio aud) throws SQLException, IOException
  {
    if (!m_hasMedia)
      return null;
    else
    {
      if (!aud.isLocal())
      {
        byte[] ctx[] = new byte[1][4000];
        try
        {
          aud.importData(ctx);
        }
        catch (SQLException e)
        {
          new IMMessage(IMConstants.ERROR, "MEDIA_SOURCE_ERR", e);
          return null;
        }
      }
      return aud.getDataInByteArray();
    }
  }
.
.
.
  void refreshPanel(boolean isFormatSupported) throws SQLException, IOException
  {
    m_hasMedia = true;
    if (isFormatSupported)
    {
      if (m_jAttrTbl == null)
      {
        m_jAttrPane.remove(m_jEmpty);
        insertProperty();
      }
      else
      {
        m_jAttrTbl.setValueAt(m_aud.getMimeType(), 0, 1);
        m_jAttrTbl.setValueAt(new Integer(m_aud.getAudioDuration()).toString(), 1, 1);
        m_jAttrTbl.setValueAt(new Integer(m_aud.getContentLength()).toString(), 2, 1);
      }
    }
    .
    .
    .
  }

5.2.7 Operations in the IMDocPanel Class

This class displays the doc panel, the product testimonials, and its attributes. This class is identical in structure and functions similarly to the IMImagePanel class. See Operations in the IMImagePanel Class for descriptions of methods.

The following code example includes the display( ), insertProperty( ), notExist( ), getDataInByteArray( ), and refreshPanel( ) methods, and highlights in bold any SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used:

  void display() throws IOException, SQLException
  {
    addControlPane();

    // Set the icon.
    m_jIcon = new JLabel(new ImageIcon(
          IMExampleFrame.class.getResource("OrdDoc.gif")
          ));
    m_jIcon.setLabelFor(m_jAttrPane);
      m_jIconPane.add(m_jIcon, BorderLayout.CENTER);

    if (notExist())
    {
      // The doc does not exist.
      m_hasMedia = false; 
      layoutEmpty(s_sNotExist);
    }
    else
    {
      // If the doc exists, show the attribute table.
      m_hasMedia = true; 
      insertProperty();
    }
  }
.
.
.
  boolean insertProperty() throws SQLException
  {
    boolean isFormatSupported = false;
    String sMimeType = m_doc.getMimeType();

    if (sMimeType == null)
      isFormatSupported = IMUtil.setProperties(m_doc);
    else
      isFormatSupported = true;

    if (!isFormatSupported)
    {
      layoutEmpty(s_sNotSupported);
    }
    else
    {
      Object[][] data = 
      {
        {"MIME Type",  m_doc.getMimeType()},
        {"Content Length", new Integer(m_doc.getContentLength()).toString()}
      };

     .
     .
     .
    }

    return isFormatSupported;
  }
.
.
.
  boolean notExist() throws SQLException, IOException
  {
    if (m_doc == null)
      return true;
    else
    {
      if (m_doc.isLocal() && (m_doc.getDataInByteArray() == null))
        return true;
      else if (!m_doc.isLocal() && (":///".equals(m_doc.getSource())))
        return true;
      else
      {
        if (!m_doc.isLocal())
        {
          BFILE bfile = m_doc.getBFILE();
          if (!bfile.fileExists())
            return true;
          else 
            return false;
        }
        else
          return false;
      }
    }
  }
.
.
.
  byte[] getDataInByteArray(OrdDoc doc) throws SQLException, IOException
  {
    if (!m_hasMedia)
      return null;
    else
    {
      if (!doc.isLocal())
      {
        byte[] ctx[] = new byte[1][4000];
        try
        {
          doc.importData(ctx, false);
        }
        catch (SQLException e)
        {
          new IMMessage(IMConstants.ERROR, "MEDIA_SOURCE_ERR", e);
          return null;
        }
      }
      return doc.getDataInByteArray();
    }
  }
.
.
.
  void refreshPanel(boolean isFormatSupported) throws SQLException, IOException
  {
    m_hasMedia = true;
    if (isFormatSupported)
    {
      if (m_jAttrTbl == null)
      {
        m_jAttrPane.remove(m_jEmpty);
        insertProperty();
      }
      else
      {
        m_jAttrTbl.setValueAt(m_doc.getMimeType(), 0, 1);
        m_jAttrTbl.setValueAt(new Integer(m_doc.getContentLength()).toString(), 1, 1);
      }
    }
.
.
.
  }

5.2.8 Operations in the IMLoadFile Class

This class loads a media stream from a file to a database for each of the media object types. First, it checks whether this PRODUCT_ID column exists in the PM.ONLINE_MEDIA table and if not, it inserts a new row into the table. Then, it creates and initializes a new media object for each media object type, updates the media data, that is, loads it into the database if it is not already stored there, and finally, sets the media attributes for each media data object.

In this class, the IMFileLoad( ) method calls the initFileChooser( ) method, then the initFileChooser( ) method calls the loadNewMedia( ) method, which does the row insertion and initializing of the media object type columns, and then calls the updateMedia( ) method to update the media and to set the media attributes.

The following code example includes the loadNewMedia( ) and UpdateMedia( ) methods, and highlights in bold any SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used as previously described:

  private void loadNewMedia() 
    throws SQLException, FileNotFoundException, SecurityException, IOException
  {
    boolean isInsertNeeded = false;
    String sQuery = null;
    OracleConnection conn = null;
    OracleResultSet rs = null;
    OraclePreparedStatement pstmt = null;

    try
    {
      conn = IMExample.getDBConnection();

      if (m_obj == null)
      {
        // First, check whether or not this product exists in the 
        // pm.online_media table. If it exists, isInsertNeeded is set to false;
        // or else, isInsertNeeded is set to true.
        sQuery = new String(
            "select product_id from pm.online_media where product_id = ?");
        pstmt = (OraclePreparedStatement) conn.prepareStatement(sQuery);
        pstmt.setInt(1, m_iProdId);
        rs = (OracleResultSet)pstmt.executeQuery();
        if (rs.next() == false)
          isInsertNeeded = true;
        else
          isInsertNeeded = false;
        rs.close();
        pstmt.close();

        if (isInsertNeeded)
        {
          // If this product is not in the pm.online_media table, 
          // insert a row in pm.online_media for this product,
          // and initialize the media object at the same time.
          sQuery = new String(
              "insert into pm.online_media (product_id, product_photo, " + 
              "product_photo_signature, product_thumbnail, product_video, " + 
              "product_audio, product_text, product_testimonials) values (" + 
              "?, ORDSYS.ORDImage.init(), ORDSYS.ORDImageSignature.init(), " +
              "ORDSYS.ORDImage.init(),  ORDSYS.ORDVideo.init(), " +
              "ORDSYS.ORDAudio.init(), null, ORDSYS.ORDDoc.init())");

          pstmt = (OraclePreparedStatement) conn.prepareCall(sQuery);
          pstmt.setInt(1, m_iProdId);
          pstmt.execute();
          pstmt.close();
        }
      }

    if (!isInsertNeeded)
    {
      // Create a new media object.
      switch (m_iTypeIdentifier)
      {
        case IMG_TYPE:
          sQuery = new String(
              "update pm.online_media set " + m_sColName + 
              " = ORDSYS.ORDImage.init() where product_id = ?");
          break;
        case AUD_TYPE:
          sQuery = new String(
              "update pm.online_media set " + m_sColName +
              " = ORDSYS.ORDAudio.init() where product_id = ?");
          break;
        case VID_TYPE:
          sQuery = new String(
              "update pm.online_media set " + m_sColName + 
              " = ORDSYS.ORDVideo.init() where product_id = ?");
          break;
        case DOC_TYPE:
          sQuery = new String(
              "update pm.online_media set " + m_sColName +  
              " = ORDSYS.ORDDoc.init() where product_id = ?"); 
          break;
        default:
          new IMMessage(IMConstants.ERROR, "UNKNOWN_TYPE");
          break;
      }

      pstmt = (OraclePreparedStatement) conn.prepareCall(sQuery);
      pstmt.setInt(1, m_iProdId);
      pstmt.execute();
      pstmt.close();
    }

      // At this point, there is a row in the online_media table
      // for this product and the desired media object is initialized.
      // In the following, we update the media object pointer and 
      // acquire the right to modify it by selecting again from the
      // database.
      //
      sQuery = new String(
          "select " + m_sColName + 
          " from pm.online_media where product_id = ? for update");
      pstmt = (OraclePreparedStatement) conn.prepareStatement(sQuery);
      pstmt.setInt(1, m_iProdId);
      rs = (OracleResultSet)pstmt.executeQuery();
      if (rs.next() == false)
        throw new SQLException();
      else
      {
        switch (m_iTypeIdentifier)
        {
          case IMG_TYPE:
            m_img = (OrdImage)rs.getORAData(1, OrdImage.getORADataFactory());
            break;
          case AUD_TYPE:
            m_aud = (OrdAudio)rs.getORAData(1, OrdAudio.getORADataFactory());
            break;
          case VID_TYPE:
            m_vid = (OrdVideo)rs.getORAData(1, OrdVideo.getORADataFactory());
            break;
          case DOC_TYPE:
            m_doc = (OrdDoc)rs.getORAData(1, OrdDoc.getORADataFactory());
            break;
          default:
            new IMMessage(IMConstants.ERROR, "UNKNOWN_TYPE");
            break;
        }

        // Update the media object.
        updateMedia();
      }

      rs.close();
      pstmt.close();
    }
    finally
    {
      IMUtil.cleanup(rs, pstmt);
    }
  }

  /**
   * Update the media and also set the media properties.
   */
  private void updateMedia()
    throws SQLException, FileNotFoundException, SecurityException, IOException
  {
    String sQuery = null;
    OracleConnection conn = null;
    byte[] ctx[] = new byte[1][64];
    OraclePreparedStatement pstmt = null;

    boolean isFormatSupported = false;

    try
    {
      conn = IMExample.getDBConnection();
      sQuery = new String(
          "update pm.online_media set " + m_sColName + 
          " = ? where product_id = ?");
      pstmt = (OraclePreparedStatement) conn.prepareCall(sQuery);
      pstmt.setInt(2, m_iProdId);

      switch (m_iTypeIdentifier)
      {
        case IMG_TYPE:
          m_img.loadDataFromFile(m_jFileChooser.getText());
          isFormatSupported = IMUtil.setProperties(m_img);
          m_img.setLocal();
          pstmt.setORAData(1, m_img);
          break;
        case AUD_TYPE:
          m_aud.loadDataFromFile(m_jFileChooser.getText());
          isFormatSupported = IMUtil.setProperties(m_aud);
          m_aud.setLocal();
          pstmt.setORAData(1, m_aud);

          // We need to update the media pointer for display,
          // because the input media pointer may be null.
          ((IMAudioPanel)m_parent).setMedia(m_aud);
          ((IMAudioPanel)m_parent).refreshPanel(isFormatSupported);
          break;
        case VID_TYPE:
          m_vid.loadDataFromFile(m_jFileChooser.getText());
          isFormatSupported = IMUtil.setProperties(m_vid);
          m_vid.setLocal();
          pstmt.setORAData(1, m_vid);

          ((IMVideoPanel)m_parent).setMedia(m_vid);
          ((IMVideoPanel)m_parent).refreshPanel(isFormatSupported);
          break;
        case DOC_TYPE:
          m_doc.loadDataFromFile(m_jFileChooser.getText());
          isFormatSupported = IMUtil.setProperties(m_doc);
          m_doc.setLocal();
          pstmt.setORAData(1, m_doc);

          ((IMDocPanel)m_parent).setMedia(m_doc);
          ((IMDocPanel)m_parent).refreshPanel(isFormatSupported);
          break;
        default:
          new IMMessage(IMConstants.ERROR, "UNKNOWN_TYPE");
          break;
      }

      pstmt.execute();
      pstmt.close();

      // Update the thumbnail image.
      if (m_iTypeIdentifier == IMG_TYPE)
      {
        if (isFormatSupported)
          m_imgThumb = IMUtil.generateThumbnail(m_iProdId, m_img, m_imgThumb);

        ((IMImagePanel)m_parent).setMedia(m_img, m_imgThumb);
        ((IMImagePanel)m_parent).refreshPanel(isFormatSupported);
      }
    }
    finally
    {
      IMUtil.cleanup(pstmt);
    }
  }

5.2.9 Operations in the IMUtil Class

This class contains common utilities, such as a generateThumbnail( ) static method, wrapper methods for the setProperties( ) methods for each media object type to separate the exceptions caused by unrecognizable formats, and finally, several cleanup methods.

The following code example includes the generateThumbnail( ) method, and highlights in bold any SQL query statements and areas in the code where Oracle Multimedia and other Oracle object types and methods are used:

static OrdImage generateThumbnail(int iProdId, OrdImage img, OrdImage imgThumb)
  throws SQLException
  {
    String sQuery = null;
    OracleConnection conn = null;
    OracleResultSet rs = null;
    OraclePreparedStatement pstmt = null;

    try
    {
      conn = IMExample.getDBConnection();

      if (imgThumb == null)
      {
        // The thumbnail media pointer is not initialized.
        // Initialize it first.
        sQuery = new String(
            "update pm.online_media set product_thumbnail = " + 
            "ORDSYS.ORDImage.init() where product_id = ?");
        pstmt = (OraclePreparedStatement) conn.prepareCall(sQuery);
        pstmt.setInt(1, iProdId);
        pstmt.execute();
        pstmt.close();

        // Acquire the new pointer and the permission to update.
        sQuery = new String("select product_thumbnail from pm.online_media " +
            "where product_id = ? for update");
        pstmt = (OraclePreparedStatement) conn.prepareStatement(sQuery);
        pstmt.setInt(1, iProdId);
        rs = (OracleResultSet)pstmt.executeQuery();
        if (rs.next() == false)
          throw new SQLException();
        else
          imgThumb = (OrdImage)rs.getORAData(1, OrdImage.getORADataFactory());

        rs.close();
        pstmt.close();
      }

      // Generate the thumbnail image.
      img.processCopy("maxScale=64 64, fileFormat=GIFF", imgThumb);

      // Update the thumbnail image in the database.
      sQuery = new String(
          "update pm.online_media set product_thumbnail = ? where product_id = ?");
      pstmt = (OraclePreparedStatement) conn.prepareCall(sQuery);
      pstmt.setORAData(1, imgThumb);
      pstmt.setInt(2, iProdId);
      pstmt.execute();
      pstmt.close();

      return imgThumb;
    }
    finally
    {
      IMUtil.cleanup(rs, pstmt);
    }
  }