ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Data-Driven SVG Apps: A Rapid Development Approach
Pages: 1, 2, 3

Creating SVG files From Data

A simplistic method of creating an SVG file would be to write Java code that makes calls to the database, gets data, and writes an SVG file. Our approach eliminates Java coding; instead, we use a framework for creating a declarative middle tier that externalizes both database calls and transformation of data from database into SVG. This approach leads to clear separation of data-access logic from presentation logic. Figure 1 depicts this framework.

Diagram.
Figure 1. Framework for SVG middle tier.

The basic tenets of the above framework are:



  1. On command from client, execute data access and update methods on the database or other data sources.
  2. Convert relational and non-relational data returned from step 1 to an Infoset (a generic data model for XML).
  3. Transform the generated infoset to target XML using XSL, JSP, or Tags.

The internals of the middle tier will be described later; however, it is completely controlled by two declarative specifications -- DDS (Declarative data source and Data access methods Specification) and DTS (Declarative Transformation Specification). DDS specifies data sources, access methods, and update methods. The current middle tier supports the following data sources: RDBMS SQL and RDBMS stored procedures, EJBs, and Java objects. Using the API of the middle tier, plug-in modules can be written to interface with other data sources. An example of DDS is provided in the "Data Sources Defined Declaratively" and "Data Access and Update Methods Defined Declaratively" sections of this article.

When the browser makes a request, a request name points to a section of the DDS XML file. This section contains data access or update methods that are executed on the database. The returned data is held in the middle tier as XML Infosets. An example of the data format is presented in the section "Format of the Retrieved Dataset."

This XML data is then transformed using DTS. Transforms currently supported by the middle tier are XSL, JSP, and Tags.

The following code demonstrates how an SVG file is created using data from a database. Our illustration will first describe the desired output, then describe the Tags transformation template file (the DTS file that declaratively specifies how this transformation will be described), and finally, the DDS file and associated XML output format.

Here is an example of a desired SVG file:

<!-- floorplan.svg -->
<svg>
<!--definitions of graphic elements that will be 
   reused
-->
   <defs> 
      <g id="power_def">
         <rect width="10" 
            height="8" 
            style="fill:red"/>
      </g>
      <g id="phone_def">
         <rect width="10" 
            height="8" 
            style="fill:blue"/>
      </g>
      <g id="ethernet_def">
         <rect width="10" 
            height="8" 
            style="fill:green"/>
      </g>
   </defs>
   <g id="drawingCanvas"> 
   <!--Start of drawing canvas -->
      <g id="power1"              <!--element 1-->
         transform="translate(410 212)"> 
         <use xlink:href="#power_def"/> 
                <!--reuse of defs, w transform -->
         <g style="visibility:hidden;" 
            desc="objectProperty">
            <text>
               <tspan desc="number">2</tspan>
            </text>
         </g>
      </g>
      <g id="phone1" 
         transform="translate(430 212)"> 
                                   <!-element 2-->
         <use xlink:href="#phone_def"/>
         <g style="visibility:hidden;" 
            desc="objectProperty">
            <text>
               <tspan desc="number">1</tspan>
               <tspan desc="phone_number">
                  904-555-1212
               </tspan>
            </text>
         </g>
      </g>
      <g id="ethernet1" 
         transform="translate(450 212)"> 
                                 <!-- element 3-->
         <use xlink:href="#ethernet_def"/>
         <g style="visibility:hidden;" 
            desc="objectProperty">
            <text>
               <tspan desc="number">1</tspan>
               <tspan desc="is_address">
                  192.168.1.5
               </tspan>
            </text>
         </g>
      </g>
   </g>
</svg>

Template SVG file

The above SVG file will be created using a tag-based transformation. Input to the tag-based transformation is the following template file.

<!-- floorplanTemplate.svg -->
<svg>
   <!--definitions of graphic elements 
      that will be reused -->
   <defs> 
      <g id="power_def">
         <rect width="10" 
            height="8" 
            style="fill:red"/>
      </g>
      <g id="phone_def">
         <rect width="10" 
            height="8" 
            style="fill:blue"/>
      </g>
      <g id="ethernet_def">
         <rect width="10" 
            height="8" 
            style="fill:green"/>
      </g>
   </defs>
   <g id="drawingCanvas"> 
                   <!--Start of drawing canvas -->
      <!--Begin Loop loop1 -->
         {{gElements}}
      <!--End loop loop1 -->
   </g>
</svg>

Compare the template file to the desired SVG file. All of the drawing elements in the canvas have been replaced with a loop tag loop1. Inside the loop tag is a replacement tag {{gElements}}. The middle tier will transform this template file by replacing loop1 and {{gElements}} with rows of data obtained from data sources. Note in this example that the entire XML code for the element is obtained from the database (a stored procedure may generate this from individual data elements in the database). An alternate method is to return individual data elements from the database and replace them in the template file. The template file, in this case, will be much larger, with all of the XML code (interspersed with replacement tags) for the drawing elements in the canvas.

Data Sources Defined Declaratively

The following is an example of the Oracle database specification in an XML definition:

<!-- section 1 of dds.xml -->
<datasource>
      <name>MyDataBase</name>
      <jdbc_url>jdbc:oracle:127.0.0.1:1521@eawp
      </jdbc_url>
      <user>ME</user>
      <pass>ANY</pass>
</datasource>

The above definition will be used every time MyDataBase is referenced in code.

Data Access and Update Methods Defined Declaratively

Next, we'll examine the data access specifications to gather data from the data source (the Oracle database).

<!-section 2 of dds.xml -->
<dataset> 
  <name>dataset1</name>
  <maindataset>
    <request>
     <javaclass>com.ai.db.DBRequestExecutor1
         </javaclass>
     <datasource>MyDataBase</datasource>
     <stmt> select image_id from annotation</stmt>
    </request>
    <request>
      <javaclass>com.ai.db.DBRequestExecutor1
      </javaclass>
      <datasource>MyDataBase</datasource>
      <stmt>select user_id 
            from users 
            where name="Jane"
            </stmt>
    </request>
    </maindataset>
    <loopdata_request>
      <name>loop1</name>
      <request>
        <javaclass>com.ai.db.DBRequestExecutor1
                                      </javaclass>
        <datasource>MyDataBase</datasource>
        <stmt> select gelements 
               from annotation_detail 
               where 
                  im_id = {image_id} 
                  and uid = {user_id} 
               </stmt>
       </request>
     </loopdata_request>
</dataset>

Notice that image_id and user_id are first obtained in maindataset, and then used in the where clause of loopdata_request select statements.

Using similar constructs, the following example describes how updates are declaratively specified. In addition, transactional guarantees are enforced across multiple requests.

<!--section 3 of dds.xml -->
<update_request>
   <name>update1</name>
     <request>
       <javaclass>com.ai.db.DBRequestExecutor1
                                      </javaclass>
      <datasource>MyDataBase</datasource>
      <stmt>update annotation_detail 
            set gelements={gelem} 
            where    
               im_id = {image_id} 
               and uid = {user_id}</stmt>
     </request>
   <!-- another request -->
     <request>
         <javaclass>com.ai.db.DBRequestExecutor1
                                      </javaclass>
      <datasource>MyDataBase</datasource>
      <stmt>update annotation_detail 
            set gelements={gelem} 
            where 
               im_id = {image_id} 
               and uid = {user_id}
               </stmt>
   </request>
       <redirect_url>http://gohere_onsuccess
                                   </redirect_url>
       <error_redirect_url_on>
           <error_code>error_code</error_code>
           <url>http://...<url>
       </error_redirect_url_on>
<update_request>

Note that gelem, image_id and user_id are passed to this request from the URL.

Pages: 1, 2, 3

Next Pagearrow