Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > updates > by-pkgid > 71d40963b505df4524269198e237b3e3 > files > 786

virtuoso-opensource-doc-6.1.4-2.fc14.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
 <head profile="http://internetalchemy.org/2003/02/profile">
  <link rel="foaf" type="application/rdf+xml" title="FOAF" href="http://www.openlinksw.com/dataspace/uda/about.rdf" />
  <link rel="schema.dc" href="http://purl.org/dc/elements/1.1/" />
  <meta name="dc.title" content="2. Installation Guide" />
  <meta name="dc.subject" content="2. Installation Guide" />
  <meta name="dc.creator" content="OpenLink Software Documentation Team ;&#10;" />
  <meta name="dc.copyright" content="OpenLink Software, 1999 - 2009" />
  <link rel="top" href="index.html" title="OpenLink Virtuoso Universal Server: Documentation" />
  <link rel="search" href="/doc/adv_search.vspx" title="Search OpenLink Virtuoso Universal Server: Documentation" />
  <link rel="parent" href="installation.html" title="Chapter Contents" />
  <link rel="prev" href="installusado.html" title="Using Visual Studio 2008 to Build an ADO.NET Data Services based Application" />
  <link rel="next" href="installcrweb.html" title="Creating a Web Browser Application to Access RDF Data Using The Virtuoso ADO.Net Provider" />
  <link rel="shortcut icon" href="../images/misc/favicon.ico" type="image/x-icon" />
  <link rel="stylesheet" type="text/css" href="doc.css" />
  <link rel="stylesheet" type="text/css" href="/doc/translation.css" />
  <title>2. Installation Guide</title>
  <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" />
  <meta name="author" content="OpenLink Software Documentation Team ;&#10;" />
  <meta name="copyright" content="OpenLink Software, 1999 - 2009" />
  <meta name="keywords" content="" />
  <meta name="GENERATOR" content="OpenLink XSLT Team" />
 </head>
 <body>
  <div id="header">
    <a name="installwfas" />
    <img src="../images/misc/logo.jpg" alt="" />
    <h1>2. Installation Guide</h1>
  </div>
  <div id="navbartop">
   <div>
      <a class="link" href="installation.html">Chapter Contents</a> | <a class="link" href="installusado.html" title="Using Visual Studio 2008 to Build an ADO.NET Data Services based Application">Prev</a> | <a class="link" href="installcrweb.html" title="Creating a Web Browser Application to Access RDF Data Using The Virtuoso ADO.Net Provider">Next</a>
   </div>
  </div>
  <div id="currenttoc">
   <form method="post" action="/doc/adv_search.vspx">
    <div class="search">Keyword Search: <br />
        <input type="text" name="q" /> <input type="submit" name="go" value="Go" />
    </div>
   </form>
   <div>
      <a href="http://www.openlinksw.com/">www.openlinksw.com</a>
   </div>
   <div>
      <a href="http://docs.openlinksw.com/">docs.openlinksw.com</a>
   </div>
    <br />
   <div>
      <a href="index.html">Book Home</a>
   </div>
    <br />
   <div>
      <a href="contents.html">Contents</a>
   </div>
   <div>
      <a href="preface.html">Preface</a>
   </div>
    <br />
   <div class="selected">
      <a href="installation.html">Installation Guide</a>
   </div>
    <br />
   <div>
      <a href="installwin32.html">Virtuoso for Windows</a>
   </div>
   <div>
      <a href="linuxinstall.html">Virtuoso for Linux (Enterprise Edition)</a>
   </div>
   <div>
      <a href="unxinstvirt.html">Virtuoso for Unix (Enterprise Edition)</a>
   </div>
   <div>
      <a href="unixpersonainstall.html">Virtuoso for Unix (Personal Edition)</a>
   </div>
   <div>
      <a href="installmacosx.html">Virtuoso for Mac OS X</a>
   </div>
   <div>
      <a href="installvsgrid.html">Virtuoso ADO.Net Data Grid Form Application</a>
   </div>
   <div>
      <a href="installvsent.html">Using Visual Studio 2008 to Build an Entity Frameworks based Windows Form Application</a>
   </div>
   <div>
      <a href="installusado.html">Using Visual Studio 2008 to Build an ADO.NET Data Services based Application</a>
   </div>
   <div class="selected">
      <a href="installwfas.html">Windows Form Application for accessing Virtuoso RDF data via SPASQL using the Virtuoso ADO.Net Provider</a>
    <div>
        <a href="#installwfasintro" title="Pre-requisites">Pre-requisites</a>
        <a href="#installwfasgetstart" title="Creating the Application">Creating the Application</a>
        <a href="#installwfasxtendcomlab" title="Extending RDFDemo to Allow Dereferencing of External IRIs">Extending RDFDemo to Allow Dereferencing of External IRIs</a>
        <a href="#installwfasxtendcomplab" title="Extending RDFDemo to Display More Compact Labels">Extending RDFDemo to Display More Compact Labels</a>
        <a href="#installwfasmodify" title="Modifying the Northwind Ontology to Add Labels">Modifying the Northwind Ontology to Add Labels</a>
        <a href="#installwfasxtendlongtext" title="Extending RDFDemo to Display Images and Longer Text Fields.">Extending RDFDemo to Display Images and Longer Text Fields.</a>
        <a href="#installwfasxtendproplab" title="Extending RDFDemo To Make The Property Labels Clickable">Extending RDFDemo To Make The Property Labels Clickable</a>
    </div>
   </div>
   <div>
      <a href="installcrweb.html">Creating a Web Browser Application to Access RDF Data Using The Virtuoso ADO.Net Provider</a>
   </div>
   <div>
      <a href="installsilver.html">Creating a Silverlight Application to consume the service</a>
   </div>
   <div>
      <a href="installnetriadd.html">Creating A Simple .NET RIA Services Application To Display Data
From Virtuoso</a>
   </div>
   <div>
      <a href="installnetriavd.html">Creating a .Net RIA Services Application That Will Update Virtuoso Data</a>
   </div>
   <div>
      <a href="clusterstcnf.html">Cluster Installation and Config</a>
   </div>
    <br />
  </div>
  <div id="text">
    <a name="installwfas" />
    <h2>2.9. Windows Form Application for accessing Virtuoso RDF data via SPASQL using the Virtuoso ADO.Net Provider</h2>
    <p>This section will guide you through creating a simple application that allows you to access RDF
data in a Virtuoso database as an Entity DataSet and explore that RDF data in an intuitive way by clicking
on dereferenceable <a href="rdfdatarepresentation.html#rdfiriidtype">IRIs</a>.</p>
    
      <a name="installwfasintro" />
    <h3>2.9.1. Pre-requisites</h3>
<ol>
      <li>Microsoft Visual Studio 2008</li>
      <li>The Virtuoso ADO.Net provider for .Net 3.5 and the Entity Framework.</li>
      <li>The example assumes that you have a local Virtuoso server with the Northwind demo database
installed. If the demo database is not already installed then download the <a href="http://download.openlinksw.com/packages/5.0/virtuoso/demo_dav.vad">demo database VAD package</a>
(demo_dav.vad) and install it. The VAD package will create a new database in Virtuoso called demo
containing the familiar Northwind tables. It will also creates <a href="http://docs.openlinksw.com/virtuoso/rdfsparqlintegrationmiddleware.html#rdfviews">RDF views</a> of the Northwind tables.
In the example we assume the database is accessible on a hostname of &quot;demo.openlinksw.com&quot; on the
default port 80, where an actually live instance of the Virtuoso Demo database is hosted. Users would
use the appropriate hostname and port number of their Virtuoso installation to create the sample
application, and would be would be localhost:8890 for a default installation or whatever the <a href="sect5_ini_URIQA.html">URIQA DefaultHost</a>
Virtuoso configuration parameter is set to when the demo database VAD package is installed.
  </li>
    </ol>
    <br />
    
      <a name="installwfasgetstart" />
    <h3>2.9.2. Creating the Application</h3>
      <p>
      <strong>Step 1 - Create a view of the RDF data.</strong>
    </p>
      <p>We want to be able to access the RDF data in Visual Studio and the easiest way to do this is to
create a view of the data that we are interested in and bind that view to a DataSet. This can be considered
as using server side <a href="rdfsparql.html">SPARQL</a>. Virtuoso supports an
<a href="rdfsparql.html#rdfsparqlinline">extension to standard SQL that allows</a> execution of SPARQL.
If a SQL query begins with the keyword SPARQL then the rest of the query is interpreted by as SPARQL.
If a SPARQL query is used as the definition of a view then that view can be manipulated using SQL like
any other view. In this way the result set from a SPARQL query can be easily accessed from Visual Studio
using ADO.Net and the Entity Framework.
      </p>
      <p>
To create a view of the customers in the Northwind first open the Virtuoso Conductor and log in as dba.
Then open iSQL from the menu on the left and execute the following statement.
      </p>
<div>
      <pre class="programlisting">

CREATE VIEW Demo.demo.sparqlview as
SPARQL
PREFIX nwind: &lt;http://demo.openlinksw.com/schemas/northwind#&gt;
SELECT DISTINCT  ?s
FROM &lt;http://demo.openlinksw.com/Northwind&gt;
WHERE {?s a nwind:Customer}
</pre>
    </div>
<p>
<strong>Note:</strong> If the view is added to the Visual Studio project as user &quot;demo&quot; (or any other
than &quot;dba&#39;), then it must be ensured that the &quot;SPARQL_SELECT&quot; and &quot;SPARQL_SPONGE&quot; roles are assigned to
this user, which can be done via the Virtuoso Conductor in the &quot;System Admin&quot; -&gt; &quot;User Accounts&quot; tab.
</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="SPARQL_SPONGE" src="../images/ui/sparqlwinf1.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.2.1. SPARQL_SPONGE</td>
    </tr>
    </table>
      <p>
      <strong>Step 2 - Create a simple grid form in Visual Studio</strong>
    </p>
<ol>
      <li>Open <strong>Visual Studio</strong> and create a new <strong>Windows Forms Application</strong> called RDFDemo.</li>
      <li>In the <strong>Form Designer</strong> drag a <strong>DataGridView</strong> on to the form.</li>
      <li>Click the <strong>Choose Data Source</strong> drop down and select <strong>Add Project Data Source</strong>.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Data Source" src="../images/ui/sparqlwinf2.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.2.1. Data Source</td>
      </tr>
        </table>
  </li>
      <li>In the <strong>Data Source Configuration Wizard</strong> choose Database and then set up a connection to the demo database on your local Virtuoso server. </li>
      <li>On the <strong>Choose Your Data Objects</strong> page expand the <strong>Views</strong> and select sparqlview.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Data Source Configuration Wizard" src="../images/ui/sparqlwinf3.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.2.1. Data Source Configuration Wizard</td>
      </tr>
        </table>
  </li>
      <li>Click <strong>Finish</strong>.</li>
      <li>In the <strong>Form Designer</strong> select dataGridView1 and change the <strong>AutoSizeColumnsMode</strong> to AllCellsExceptHeader.</li>
      <li>Select the <strong>DefaultCellStyle</strong> and click on the ellipsis. This will open the
<strong>CellStyleBuilder</strong>. Change the <strong>ForeColor</strong> to Blue.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="CellStyleBuilder" src="../images/ui/sparqlwinf4.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.2.1. CellStyleBuilder</td>
      </tr>
        </table>
  </li>
      <li>Expand <strong>Font</strong> and change <strong>Underline</strong> to True.
Click <strong>OK</strong>.</li>
    </ol>
      <p>
      <strong>Step 3 - Change the mapping of the DataSet.</strong>
    </p>
<p>In the Solution Explorer you will now have a DataSet called DemoDataSet.xsd. If you double click on
this it opens the DataSet Designer. Select the column called s in the sparqlview table and in the Properties
pane change the DataType from System.String to System.Object.</p>
<p>The data returned by a SPARQL query can either be an <a href="rdfdatarepresentation.html#rdfiriidtype">IRI</a> or a
literal value. In order to distinguish between the two the Virtuoso ADO.Net provider defines an additional
data type, SQLExtendedString. By setting the column type to System.Object we can cast the fetched data back
to SQLExtendedString and find out if an individual value is an IRI or a literal and handle it appropriately.
</p>
<p>
      <strong>Step 4 - Create the on_click event handler for the cells in the DataGridView.</strong>
    </p>
<p>Return to the <strong>Form Designer</strong> and double click on the cell of the
<strong>DataGridView</strong>. This creates the <strong>dataGridView1_CellContentClick</strong> method in Form1.cs. This is the method that handles clicking on IRI objects in the grid.
</p>
<p>Paste in the following block of code into the body of the <strong>dataGridView1_CellContentClick</strong> method.
</p>
<div>
      <pre class="programlisting">
int column = e.ColumnIndex;
 object o = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
 Type t = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType;

 if (o is SqlExtendedString)
 {
     SqlExtendedString se = (SqlExtendedString) o;
     ExtendedStringHandler seHandler = new ExtendedStringHandler(se, this.sparqlviewTableAdapter.Connection);
     seHandler.displayData();
 }
 else if (o is SqlRdfBox)
 {
     //doesn&#39;t do anything at the moment
 }

</pre>
    </div>
<p>
As we are using the SQLExtendedString extension from the Virtuoso ADO.Net provider you will also need to add
</p>
<div>
      <pre class="programlisting">
using OpenLink.Data.Virtuoso;
</pre>
    </div>
<p>
at the top of the file.
</p>
<p>
      <strong>Step 5 - Create a class to handle exploring the RDF data.</strong>
    </p>
<ul>
  <li>Add a new C# class to the project called ExtendedStringHandler, by Right clicking on
RDFDemo in the <strong>Solution Explorer</strong> and <strong>Add</strong> a
<strong>Class</strong>.</li>
  <li>Add the following using statements to the top of the file
<div>
          <pre class="programlisting">
using OpenLink.Data.Virtuoso;
using System.Data;
using System.Windows.Forms;
using System.Drawing;
using System.Data.Mapping;
using System.Data.Common;
</pre>
        </div>
</li>
  <li>Paste the following block of code into the class definition.
<div>
          <pre class="programlisting">
StringBuilder DescribeCommand;
VirtuosoConnection ParentConnection;
List&lt;Label&gt; labelList = new List&lt;Label&gt;();
List&lt;TextBox&gt; textBoxList = new List&lt;TextBox&gt;();
DescribeDataSet describeDataSet = new DescribeDataSet();
Boolean isIRI = false;

public ExtendedStringHandler(SqlExtendedString iri, VirtuosoConnection parentConnection)
 {
     ParentConnection = parentConnection;
     if (iri.IriType == SqlExtendedStringType.IRI)
     {
         isIRI = true;
         DescribeCommand = new StringBuilder(&quot;sparql select * from &lt;http://demo.openlinksw.com/Northwind&gt; where {&lt;&quot; + iri.ToString() + &quot;&gt; ?p ?o}&quot;);      // Replace demo.openlinksw.com with your  URIQA DefaultHost setting
     }
 }

 public string describeCommandText
 {
     get
     {
         return DescribeCommand.ToString();
     }
 }

 public void getDescribeData()
 {
      VirtuosoCommand myCommand = new VirtuosoCommand(this.describeCommandText, this.ParentConnection);
     VirtuosoDataAdapter myAdapter = new VirtuosoDataAdapter();
     myAdapter.SelectCommand = myCommand;
     myAdapter.Fill(describeDataSet.DataTable1);
 }

 public void displayData()
 {
     if (isIRI)
     {
         getDescribeData();
         Form describeForm = new Form();
         describeForm.AutoScroll = true;
         describeForm.Width = 840;

         Label label1 = new Label();
         label1.AutoSize = true;
         label1.Font = new Font(label1.Font.FontFamily, label1.Font.Size + 3.0F, label1.Font.Style | FontStyle.Bold, label1.Font.Unit);
         describeForm.Controls.Add(label1);

         DataTable table1 = describeDataSet.Tables[0];
         if (table1.Rows.Count == 0)
             label1.Text = &quot;No Details Available&quot;;
         else
         {
             foreach (DataRow row in table1.Rows)
                 if (row[0].ToString() == &quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&quot;)
                 {
                     StringBuilder title = new StringBuilder(row[1].ToString() + &quot; details&quot;);
                     label1.Text = title.ToString();
                     break;
                 }

             foreach (DataRow row in table1.Rows)
             {
                 Label propertyLabel = new Label();
                 TextBox valueBox = new TextBox();
                 valueBox.Width = 400;

                 object property = row[0];
                 object value = row[1];

                 if (value is SqlExtendedString)
                 {
                     valueBox.ForeColor = Color.Blue;
                     valueBox.Font = new Font(valueBox.Font.FontFamily, valueBox.Font.Size, valueBox.Font.Style | FontStyle.Underline, valueBox.Font.Unit);
                 }
                 propertyLabel.Text = row[0].ToString();
                 propertyLabel.AutoEllipsis = true;
                 propertyLabel.AutoSize = false;
                 propertyLabel.Width = propertyLabel.PreferredWidth &gt; 380 ? 380 : propertyLabel.PreferredWidth;

                 Binding bind = new Binding(&quot;Text&quot;, row[1], &quot;&quot;);
                 valueBox.DataBindings.Add(bind);

                 labelList.Add(propertyLabel);
                 textBoxList.Add(valueBox);
             }

             for (int i = 0; i &lt; table1.Rows.Count; i++)
             {
                 textBoxList[i].Click += new EventHandler(this.iri_Click);
                 labelList[i].Location = new Point(10, i * 20 + 50);
                 textBoxList[i].Location = new Point(400, i * 20 + 50);
                 describeForm.Controls.Add(labelList[i]);
                 describeForm.Controls.Add(textBoxList[i]);
             }

             describeForm.Height = labelList.Count * 20 + 100 &gt; 500 ? 500 : labelList.Count * 20 + 100;
         }
         describeForm.ShowDialog();
     }
     else
     {
         Form blankForm = new Form();
         Label label1 = new Label();
         label1.Text = &quot;Blank Node&quot;;
         label1.Font = new Font(label1.Font.FontFamily, label1.Font.Size + 3.0F, label1.Font.Style | FontStyle.Bold, label1.Font.Unit);
         blankForm.ShowDialog();
     }
 }

 public void iri_Click(object sender, EventArgs e)
 {
     int boxNum = 0;

     for (int i = 0; i &lt; textBoxList.Count; i++)
     {
         if (sender == textBoxList[i])
         {
             boxNum = i;
             break;
         }
     }

    Object o = describeDataSet.DataTable1.Rows[boxNum][1];
     if (o is SqlExtendedString)
     {
         SqlExtendedString se = (SqlExtendedString)o;
         ExtendedStringHandler seHandler = new ExtendedStringHandler(se, ParentConnection);
         seHandler.displayData();
     }
     else if (o is SqlRdfBox)
     {
        //doesn&#39;t do anything at the moment
    }
 }
</pre>
        </div>
</li>
</ul>
<p>
The ExtendedStringHandler class creates a new SPARQL query based on the IRI that was clicked. This
query is executed against Virtuoso using the ADO.Net connection in the same way that any SQL statement
would be executed across an ADO.Net connection. This can be considered as Client Side SPARQL. The result
set from the query describes the selected object and is returned as an ADO.Net DataAdapter. The
DataAdapter is used to fill a DataTable which is displayed on a new form. We now need to add the
new DataSet to the project and define the DataTable that will hold the query results.
</p>
      <p>
      <strong>Step 6 - Add a new DataSet to hold the query results.</strong>
    </p>
<ol>
      <li>Right click RDFDemo in the <strong>Solution Explorer</strong> and add a new
<strong>DataSet</strong>. Call the new <strong>DataSet</strong> DescribeDataSet.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Add a new DataSet" src="../images/ui/sparqlwinf5.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.2.1. Add a new DataSet</td>
      </tr>
        </table>
</li>
      <li>Double click on DescribeDataSet in the <strong>Solution Explorer</strong> to open the
<strong>DataSet</strong> Designer and drag a <strong>DataTable</strong> from the
<strong>Toolbox</strong> into it.</li>
    <li>Add two columns, p and o, to the <strong>DataTable</strong> and set the
<strong>DataType</strong> of each column to System.Object.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Add two columns" src="../images/ui/sparqlwinf6.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.2.1. Add two columns</td>
      </tr>
        </table>
    </li>
    </ol>
      <p>
      <strong>Step 7 - Build and run the application.</strong>
    </p>
<p>You should see a form displaying all the Northwind customers, like this.
</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="Northwind customers" src="../images/ui/sparqlwinf7.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.2.2. Northwind customers</td>
    </tr>
    </table>
<p>When any customer is clicked it opens a new form showing customer details.
</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="Customer details" src="../images/ui/sparqlwinf8.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.2.3. Customer details</td>
    </tr>
    </table>
<p>Clicking on the links in the new form allows you to drill down further to get
order, product, location details etc.
</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="Order, product, location details" src="../images/ui/sparqlwinf9.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.2.4. Order, product, location details</td>
    </tr>
    </table>
<p>and</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="Order, product, location details" src="../images/ui/sparqlwinf10.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.2.5. Order, product, location details</td>
    </tr>
    </table>
      <p>
      <strong>Next Steps</strong>
    </p>
<p>
You will notice if you keep clicking on the links that this application will only display data that
is held in the Northwind graph. Clicking on an external link, for example the link to Berlin in
dbpedia, http://dbpedia.org/resource/Berlin, results in a empty window and an error message. The
next step is to extend this application so that it can handle dereferencing external IRIs.
</p>
    <br />
    
      <a name="installwfasxtendcomlab" />
    <h3>2.9.3. Extending RDFDemo to Allow Dereferencing of External IRIs</h3>
<p>
This section will guide you through extending the application created in
<a href="installwfas.html#installwfasgetstart">Creating a Windows Forms Application To Access RDF Data Using The
Virtuoso ADO.Net Provider</a> so that it will dereference external IRIs.
</p>
      <p>
      <strong>Pre-requisites</strong>
    </p>
<ol>
    <li>A working copy of the RDFDemo application created in
<a href="installwfas.html#installwfasgetstart">Creating a Windows Forms Application To
Access RDF Data Using The Virtuoso ADO.Net Provider.</a>
    </li>
    </ol>
    
      <a name="installwfasxtendcomlabextappl" />
    <h4>2.9.3.1. Extending the Application</h4>
<p>In RDFDemo when the sparql endpoint is queried to get the description of the selected item it executes
a query that is restricted to the local Northwind dataset. The query is something like
</p>
<div>
      <pre class="programlisting">
SPARQL
PREFIX nwind: &lt;http://demo.openlinksw.com/schemas/northwind#&gt;
SELECT DISTINCT  ?s
FROM &lt;http://demo.openlinksw.com/Northwind&gt;
WHERE {?s a nwind:Customer}
</pre>
    </div>
<p>If you examine the ExtendedStringHandler class you will see that the dataset clause, from
&lt;http://localhost:8890/Northwind&gt;, is hard coded. This means that when when the selected IRI is
a link to an external data store, such as dbpedia, there is no matching data and an error is displayed.
If the application is to be able to dereference external IRIs then the hard coded dataset clause needs
to be removed and then we can use a Virtuoso extension to SPARQL, get:soft, that tells Virtuoso that it
needs to go and look elsewhere for the graph. However, this will result in a loss of performance when
exploring the local Northwind dataset. To minimize the impact on performance we will first query the
local Northwind dataset and if there are no matching triples returned then we will use a more generic
query that will look elsewhere for matching data.
</p>
      <p>
      <strong>Step 1 - Add the alternative query to the ExtendedString Class.</strong>
    </p>
<ul>
  <li>Open the RDFDemo project in Visual Studio </li>
  <li>Open the ExtendedStringHandler class.</li>
  <li>Remove DescribeCommand by removing the line
<div>
          <pre class="programlisting">
StringBuilder DescribeCommand;
</pre>
        </div>
<p>
and substitute the following:
</p>
<div>
          <pre class="programlisting">
StringBuilder DescribeCommandSimple, DescribeCommandGeneral;
</pre>
        </div>
</li>
  <li>In the ExtendedStringHandler constructor the sparql query that was DescribeCommand becomes
DescribeCommandSimple and we define a new query for DescribeCommandGeneral.
<div>
          <pre class="programlisting">
DescribeCommandSimple = new StringBuilder(&quot;sparql select * from &lt;http://demo.openlinksw.com/Northwind&gt; where {&lt;&quot; + iri.ToString() + &quot;&gt; ?p ?o}&quot;);       // Replace demo.openlinksw.com with your  URIQA DefaultHost setting
DescribeCommandGeneral = new StringBuilder(&quot;sparql define get:soft &quot; + &#39;&quot;&#39;.ToString() + &quot;soft&quot; + &#39;&quot;&#39;.ToString() + &quot; select * from &lt;&quot; + iri.ToString() + &quot;&gt; where { &lt;&quot; + iri.ToString() + &quot;&gt; ?p ?o }&quot;);
</pre>
        </div>
</li>
  <li>The single describeCommand property needs to be replaced with the two new properties,
DescribeCommandSimple and DescribeCommandGeneral
<div>
          <pre class="programlisting">
public string describeCommandSimpleText
{
    get
    {
        return DescribeCommandSimple.ToString();
    }
}
public string describeCommandGeneralText
{
    get
    {
        return DescribeCommandGeneral.ToString();
    }
}
</pre>
        </div>
</li>
  <li>Finally, the getDescribeData method needs changing to:
<div>
          <pre class="programlisting">
public void getDescribeData()
{
    VirtuosoCommand myCommand = new VirtuosoCommand(this.describeCommandSimpleText, this.ParentConnection);
    VirtuosoDataAdapter myAdapter = new VirtuosoDataAdapter();
    myAdapter.SelectCommand = myCommand;
    myAdapter.Fill(describeDataSet.DataTable1);
    // Tried the simple version if fails to get the data try
    // to look elsewhere.
    if (describeDataSet.DataTable1.Rows.Count == 0)
    {
        myCommand.CommandText = describeCommandGeneralText;
        myAdapter.Fill(describeDataSet.DataTable1);
    }
}
</pre>
        </div>
</li>
</ul>
      <p>
      <strong>Step 2 - Build and Run the Application</strong>
    </p>
<p>
You will see the same starting form:
</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="Build and Run the Application" src="../images/ui/sparqlwinf11.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.3.1.1. Build and Run the Application</td>
    </tr>
    </table>
<p>
Select a Customer and then select the link to the City in dbpedia. This will now open up another window
displaying information about the city from dbpedia. Be patient as it may take a little while to open.
</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="Customer" src="../images/ui/sparqlwinf12.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.3.1.2. Customer</td>
    </tr>
    </table>
      <p>
      <strong>Step 3 - Changing the Form Title</strong>
    </p>
<p>
Notice that in displayData method that we look for a
http://www.w3.org/1999/02/22-rdf-syntax-ns#type and create a title for the form from it.
</p>
<div>
      <pre class="programlisting">
foreach (DataRow row in table1.Rows)
  if (row[0].ToString() == &quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&quot;)
  {
      StringBuilder title = new StringBuilder(row[1].ToString() + &quot; details&quot;);
      label1.Text = title.ToString();
      break;
  }
</pre>
    </div>
<p>
This worked well for the Northwind subjects but less well now we are getting data from other graphs.
To change the title of the forms used to display the data:
</p>
<ul>
  <li>Add an new member variable to hold the IRI that we exploring to the bock of member variables
<div>
          <pre class="programlisting">
StringBuilder DescribeCommandSimple, DescribeCommandGeneral;
VirtuosoConnection ParentConnection;
List&lt;Label&gt; labelList = new List&lt;Label&gt;();
List&lt;TextBox&gt; textBoxList = new List&lt;TextBox&gt;();
DescribeDataSet describeDataSet = new DescribeDataSet();
Boolean isIRI = false;
SqlExtendedString ParentIRI;
</pre>
        </div>
</li>
  <li>Assign a value to ParentIRI in the constructor:
<div>
          <pre class="programlisting">
public ExtendedStringHandler(SqlExtendedString iri, VirtuosoConnection parentConnection)
  {
      ParentConnection = parentConnection;
      if (iri.IriType == SqlExtendedStringType.IRI)
      {
          ParentIRI = iri;
          isIRI = true;
          DescribeCommandSimple = new StringBuilder(&quot;sparql select * from &lt;http://demo.openlinksw.com/Northwind&gt; where {&lt;&quot; + iri.ToString() + &quot;&gt; ?p ?o}&quot;);      // Replace demo.openlinksw.com with your  URIQA DefaultHost setting
          DescribeCommandGeneral = new StringBuilder(&quot;sparql define get:soft &quot; + &#39;&quot;&#39;.ToString() + &quot;soft&quot; + &#39;&quot;&#39;.ToString() + &quot; select * from &lt;&quot; + iri.ToString() + &quot;&gt; where { &lt;&quot; + iri.ToString() + &quot;&gt; ?p ?o }&quot;);
      }
  }
</pre>
        </div>
</li>
  <li>Remove the existing foreach block that sets the form title and replace with the following lines:
<div>
          <pre class="programlisting">
StringBuilder title = new StringBuilder(ParentIRI.ToString() + &quot; details&quot;);
label1.Text = title.ToString();
</pre>
        </div>
</li>
  <li>Build and run the application.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Build and run the application" src="../images/ui/sparqlwinf13.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.3.1.1. Build and run the application</td>
      </tr>
        </table>
</li>
</ul>
<p>
      <strong>Next Steps</strong>
    </p>
<p>The application now allows you to explore data and follow links from your locally held data into the
external web of data. Looking at the data displayed in the form it would be nice to make the labels for
the properties more compact. The label http://dbpedia.org/property/population is a very precise definition
but for our purposes it would be clearer to label the property just population. In the next step will be
to modify the application so that it displays more readable labels.
</p>
    <br />
    <br />
    
      <a name="installwfasxtendcomplab" />
    <h3>2.9.4. Extending RDFDemo to Display More Compact Labels</h3>
<p>
This section will guide you through extending the application created in
<a href="installwfas.html#installwfasxtendcomlab">Extending RDFDemo to Allow Dereferencing of External IRIs</a> so that the data is displayed in a more readable form.
</p>
      <p>
      <strong>Pre-requisites</strong>
    </p>
<ol>
    <li>A working copy of the RDFDemo application created in
<a href="installwfas.html#installwfasxtendcomlab">Extending RDFDemo to Allow Dereferencing of External IRIs</a>
    </li>
    </ol>
    
      <a name="installwfasxtendcomplabextapp" />
    <h4>2.9.4.1. Extending the Application</h4>
<p>The RDF demo application presents the user with a list of Customers from the Northwind database in
the form of dereferenceable IRIs. When a customer is selected from the list the application uses a sparql
query to describe that customer and the results are displayed in a form as rows of labels and data. The
labels correspond to RDF predicates and the data corresponds to RDF objects while the subject is the
customer initially selected. In many cases the objects are dereferencable IRIs which are then used as
the subject when the &#39;drilling down&#39; into the data. However, the predicates are also IRIs so it is
possible to gain more information about these as well.
</p>
<p>The RDF Schema defines a property http://www.w3.org/2000/01/rdf-schema#label that may be used to
provide a human-readable version of a resource&#39;s name. We can obtain further details of each of the
predicates in a resultset and check to see if one of the properties is an
http://www.w3.org/2000/01/rdf-schema#label. If it is we can use the associated text as the label in
our form instead of the the predicate IRI. The benefit should be a more human readable form.
</p>
      <p>
      <strong>Step 1 - Add a New Method to Get the Label Text</strong>
    </p>
<p>This method takes the predicate IRI and issues a sparql query to get its description. It then
cycles through the returned dataset to find a http://www.w3.org/2000/01/rdf-schema#label. If there is
one then the associated text is returned by the method. Otherwise the method returns the IRI string.
</p>
<ul>
  <li>Add the following method to the ExtendedStringHandlerClass
<div>
          <pre class="programlisting">
private string getLabelText(Object label)
  {
      string labelText = label.ToString();
      if (label is SqlExtendedString)
      {
          SqlExtendedString se = (SqlExtendedString)label;
          StringBuilder getLabelCommandText = new StringBuilder(&quot;sparql define get:soft \&quot;soft\&quot; select * from &lt;&quot; + se.ToString() + &quot;&gt; where {&lt;&quot; + se.ToString() + &quot;&gt; ?p ?o}&quot;);
          VirtuosoCommand getLabelCommand = new VirtuosoCommand(getLabelCommandText.ToString(), ParentConnection);
          VirtuosoDataAdapter getLabelAdapter = new VirtuosoDataAdapter();
          getLabelAdapter.SelectCommand = getLabelCommand;
          DataSet getLabelDataSet = new DataSet();
          try
          {
              getLabelAdapter.Fill(getLabelDataSet);
              foreach (DataRow getLabelRow in getLabelDataSet.Tables[0].Rows)
              {
                  if (getLabelRow[0].ToString() == &quot;http://www.w3.org/2000/01/rdf-schema#label&quot;)
                  {
                      labelText = getLabelRow[1].ToString();
                      break;
                  }
              }
          }
          catch
          {
          }
      }
      return labelText;
  }
</pre>
        </div>
</li>
  <li>Change the line in displayData from
<div>
          <pre class="programlisting">
propertyLabel.Text = row[0].ToString();
</pre>
        </div>
</li>
  <li>to
<div>
          <pre class="programlisting">
propertyLabel.Text = getLabelText(row[0]);
</pre>
        </div>
</li>
</ul>
       <p>
      <strong>Step 1 - Add a New Method to Get the Label Text</strong>
    </p>
<p>When you run the application you will see that the initial form is the same. In fact, when you
select the Customer you will also see that the customer details are also the same. It is only when you
start exploring data outside the Northwind graph that you will see the labels in the form change.
</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="Northwind graph" src="../images/ui/sparqlwinf14.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.4.1.1. Northwind graph</td>
    </tr>
    </table>
    <p>
      <strong>Next Steps</strong>
    </p>
<p>It is clear from running the application that the Northwind ontology does not define an
http://www.w3.org/2000/01/rdf-schema#label for its members. In order to benefit from this modified
version of RDFDemo we need to update our Northwind ontology so that
http://www.w3.org/2000/01/rdf-schema#label is defined for each resource. The next step will be to modify
our Northwind ontology.
</p>
     <br />
    <br />
    
      <a name="installwfasmodify" />
    <h3>2.9.5. Modifying the Northwind Ontology to Add Labels</h3>
<p>This section will guide you through modifying the Northwind Ontology created when you installed
the <a href="http://download.openlinksw.com/packages/5.0/virtuoso/demo_dav.vad">demo database VAD package</a> so that each resources is identified by an
http://www.w3.org/2000/01/rdf-schema#label. This will improve the readability of the information displayed by
the application created in <a href="installwfas.html#installwfasxtendcomplab">Extending RDFDemo to Display More Compact Labels</a>.
</p>
<p>
      <strong>Pre-requisites</strong>
    </p>
<ol>
    <li>A working copy of the RDFDemo application created in <a href="installwfas.html#installwfasxtendcomplab">Extending RDFDemo to Display More Compact Labels</a>
    </li>
    </ol>
    
      <a name="installwfasmodifyeditont" />
    <h4>2.9.5.1. Editing the Ontology</h4>
    <p>
      <strong>Get a Working Copy of the Northwind Ontology</strong>
    </p>
<p>The the file describing the Northwind Ontology, nw.owl, is installed in the DAV when the demo vad
is loaded. To get a working copy open the Virtuoso Conductor and log in as dba. Select WebDAV Browser in
the navigation panel on the left. This will open a window that allows you to browse the WebDAV Repository.
The Northwind Ontology file can be found in DAV/VAD/demo/sql. Take a copy of the file.
</p>
    <p>
      <strong>Editing nw.owl</strong>
    </p>
<p>In the first instance is edited nw.owl so that the property name consistently begin with a lower
case letter. This matches the results for describing resources held in the Northwind database. Also are
added missing properties so that there should be a label in all cases.
</p>
    <p>
      <strong>Registering the Changes in Virtuoso</strong>
    </p>
<p>There are two methods for registering the changes in Virtuoso:
</p>
<ol>
      <li>Method I:
    <ul>
      <li>Copy the edited version of nw.owl back into the DAV.</li>
      <li>In isql, load the script load_ontology_dav.sql and execute it. The new version of
nw.owl will then be used</li>
    </ul>
</li>
      <li>
    <ul>
      <li>Ensure that your new version of nw.owl is in a folder accessible by Virtuoso. You may
need to edit your virtuoso.ini file and restart the server.</li>
      <li>In isql, load the script load_ontology_file.sql and edit it so that it has the full
path to the new version of nw.owl</li>
      <li>Run the script. The new version of nw.owl will then be used.</li>
    </ul>
</li>
    </ol>
    <p>Modify RDFDemo so that it looks for the graph used to describe the Northwind data and
searches that graph for the predicate details:</p>
<ol>
    <li>Add a new member variable to the ExtendedStringHandler class to hold the graphs that
we need to search for the predicate information.
<div>
          <pre class="programlisting">
StringBuilder DescribeCommandSimple, DescribeCommandGeneral;
VirtuosoConnection ParentConnection;
List&lt;Label&gt; labelList = new List&lt;Label&gt;();
List&lt;TextBox&gt; textBoxList = new List&lt;TextBox&gt;();
List&lt;String&gt; graphList = new List&lt;String&gt;();
DescribeDataSet describeDataSet = new DescribeDataSet();
Boolean isIRI = false;
SqlExtendedString ParentIRI;
</pre>
        </div>
    </li>
      <li>In displayData, after we have set the title of the form, add the following block of code:
<div>
          <pre class="programlisting">
// Later we will want to get property labels and for that
 // we will need the graph where the resource is defined.
foreach (DataRow row in table1.Rows)
     if (row[0].ToString() == &quot;http://www.openarchives.org/ore/terms/isDescribedBy&quot;
    &amp;&amp; row[1].ToString() != ParentIRI.ToString())
     {
         String graph = row[1].ToString();
         graphList.Add(graph);
     }
</pre>
        </div>
</li>
      <li>Replace the existing getLabelText method with an extended version
<div>
          <pre class="programlisting">
 private string getLabelText(Object label)
  {
      string labelText = label.ToString();
      if (label is SqlExtendedString)
      {
          Boolean foundLabel = false;
          SqlExtendedString se = (SqlExtendedString)label;
          VirtuosoDataAdapter getLabelAdapter = new VirtuosoDataAdapter();
          DataSet getLabelDataSet = new DataSet();

          //Try finding it in resources graph first
          foreach (String graph in graphList)
          {
              StringBuilder getLabelCommandText = new StringBuilder(&quot;sparql select * from &lt;&quot; + graph + &quot;&gt; where {&lt;&quot; + se.ToString() + &quot;&gt; ?p ?o}&quot;);
              VirtuosoCommand getLabelCommand = new VirtuosoCommand(getLabelCommandText.ToString(), ParentConnection);
              getLabelAdapter.SelectCommand = getLabelCommand;

              try
              {
                  getLabelAdapter.Fill(getLabelDataSet);
                  foreach (DataRow getLabelRow in getLabelDataSet.Tables[0].Rows)
                  {
                      if (getLabelRow[0].ToString() == &quot;http://www.w3.org/2000/01/rdf-schema#label&quot;)
                      {
                          labelText = getLabelRow[1].ToString();
                          foundLabel = true;
                          break;
                      }
                  }
              }
              catch
              {
              }
              if (foundLabel)
                  break;
          }
          // If we still have no label try the predicate itself as the graph
          if (!foundLabel)
          {
              StringBuilder getLabelCommandText = new StringBuilder(&quot;sparql define get:soft \&quot;soft\&quot; select * from &lt;&quot; + se.ToString() + &quot;&gt; where {&lt;&quot; + se.ToString() + &quot;&gt; ?p ?o}&quot;);
              VirtuosoCommand getLabelCommand = new VirtuosoCommand(getLabelCommandText.ToString(), ParentConnection);
              getLabelAdapter.SelectCommand = getLabelCommand;
              try
              {
                  getLabelAdapter.Fill(getLabelDataSet);
                  foreach (DataRow getLabelRow in getLabelDataSet.Tables[0].Rows)
                  {
                      if (getLabelRow[0].ToString() == &quot;http://www.w3.org/2000/01/rdf-schema#label&quot;)
                      {
                          labelText = getLabelRow[1].ToString();
                          break;
                      }
                  }
              }
              catch
              {
              }
          }
      }
      return labelText;
  }
</pre>
        </div>
<p>This extended method first checks the graphs in the graph list for the predicate information then
if no label has been found tries the predicate itself as the graph.
</p>
</li>
      <li>Build and run, the Northwind resources should now be correctly and concisely labeled
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Northwind resources" src="../images/ui/sparqlwinf15.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.5.1.1. Northwind resources</td>
      </tr>
        </table>
</li>
    </ol>
<p>
</p>
    <p>
      <strong>Improving The Appearance of the Form</strong>
    </p>
<p>The following changes are not strictly necessary but improve the appearance of the form:
</p>
<ul>
  <li>Line up the right hand edge of the labels with the text boxes by setting TextAlign to
MiddleRight and reduce the width of the labels.
<div>
          <pre class="programlisting">
propertyLabel.Text = getLabelText(row[0]);
propertyLabel.AutoEllipsis = true;
propertyLabel.AutoSize = false;
propertyLabel.Width = 130;
propertyLabel.TextAlign = ContentAlignment.MiddleRight;
</pre>
        </div>
</li>
  <li>Make the form narrower:
<div>
          <pre class="programlisting">
describeForm.Width = 660;
</pre>
        </div>
</li>
  <li>Alter the positioning of the labels and TextBoxes on the form:
<div>
          <pre class="programlisting">
textBoxList[i].Click += new EventHandler(this.iri_Click);
labelList[i].Location = new Point(10, i * 22 + 50);
textBoxList[i].Location = new Point(150, i * 22 + 50);
describeForm.Controls.Add(labelList[i]);
describeForm.Controls.Add(textBoxList[i]);
</pre>
        </div>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Alter the positioning" src="../images/ui/sparqlwinf16.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.5.1.1. Alter the positioning</td>
      </tr>
        </table>
</li>
</ul>
    <p>
      <strong>Next Steps</strong>
    </p>
<p>The image below shows some of the information about an employee in the Northwind dataset.
</p>
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
    <tr>
     <td>
          <img alt="employee" src="../images/ui/sparqlwinf17.png" />
     </td>
    </tr>
    <tr>
        <td>Figure: 2.9.5.1.1. employee</td>
    </tr>
    </table>
<p>In the next step we will extend the application so the images and web pages can be viewed
and long text fields are displayed in full.
</p>
    <br />
    <br />

    
      <a name="installwfasxtendlongtext" />
    <h3>2.9.6. Extending RDFDemo to Display Images and Longer Text Fields.</h3>
<p>This section will guide you through extending RDFDemo so that longer text fields can be displayed
as a block of text and so that links to images and web pages can be viewed in a browser window.
</p>
<p>
      <strong>Pre-requisites</strong>
    </p>
<ol>
    <li>A working copy of the RDFDemo application created in
<a href="installwfas.html#installwfasmodify">Modifying the Northwind Ontology to Add Labels</a>
    </li>
    </ol>
    
      <a name="installwfasxtendlongtextmodf" />
    <h4>2.9.6.1. Modifying the Application</h4>
    <p>
      <strong>Displaying Text</strong>
    </p>
<p>We will modify the form that show the details of the selected item so that when the text in the boxes
is too long to be seen in full a button will appear beside the box on the form and if you click the button
the complete text will be displayed in a separate window.
</p>
<ol>
      <li>Add a new class, MoreButton that extends System.Windows.Forms.Button.
<ul>
  <li>In the <strong>Solution Explorer</strong> right click on the RDFDemo project and select
<strong>Add</strong> then <strong>New Item</strong>.</li>
  <li>Add a new class called MoreButton.cs.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
        <tr>
         <td>
                  <img alt="Add a new class" src="../images/ui/sparqlwinf18.png" />
         </td>
        </tr>
        <tr>
                <td>Figure: 2.9.6.1.1. Add a new class</td>
        </tr>
            </table>
</li>
  <li>The following using statement goes at the top of the file:
<div>
              <pre class="programlisting">
using System.Windows.Forms;
</pre>
            </div>
</li>
  <li>The MoreButton class must inherit from System.Windows.Forms.Button
so the class definition line should look like this:
<div>
              <pre class="programlisting">
class MoreButton : Button
</pre>
            </div>
</li>
  <li>Add the following code to the body of the MoreButton class:
<div>
              <pre class="programlisting">
 String longText;

 public MoreButton(String text)
 {
     longText = text;
     this.Text = &quot;More&quot;;
 }

 protected override void  OnClick(EventArgs e)
 {
     Form moreForm = new Form();
     TextBox moreBox = new TextBox();
     moreBox.Text = longText;
     moreBox.Width = 300;
     moreBox.Height = 250;
     moreBox.ScrollBars = ScrollBars.Vertical;
     moreBox.Multiline = true;
     moreBox.WordWrap = true;
     moreBox.Select(0, 0);
     moreBox.ReadOnly = true;
     moreForm.Controls.Add(moreBox);
     moreForm.Width = 320;
     moreForm.Height = 280;
     moreForm.ShowDialog();
 }
</pre>
            </div>
</li>
</ul>
</li>
      <li>In displayData in the ExtendedStringHandler class, when the labels and TextBoxes are added to
the form check if the text is too big for the box. If it is then add a MoreButton that will display all
the text in a separate window.
<div>
          <pre class="programlisting">
if (textBoxList[i].DataBindings[0].DataSource.ToString().Length &gt; 80
    &amp;&amp; !(textBoxList[i].DataBindings[0].DataSource is SqlExtendedString))
{
    moreButtonList.Add(new MoreButton(textBoxList[i].DataBindings[0].DataSource.ToString()));
    moreButtonList[moreButtonList.Count - 1].Location = new Point(550, i * 22 + 50);
    describeForm.Controls.Add(moreButtonList[moreButtonList.Count -1]);
}
</pre>
        </div>
</li>
      <li>We will also need a list to hold the buttons as they are created so the following needs to
be added to the member variables at the top of the ExtendedStringHandler class.
<div>
          <pre class="programlisting">
List&lt;MoreButton&gt; moreButtonList = new List&lt;MoreButton&gt;();
</pre>
        </div>
</li>
      <li>Build and run the application. If you click through to an Employee page you will see the
Notes field now has a button labeled More next to it. If you click on that button the text from the Notes
field is displayed in a new window.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Notes" src="../images/ui/sparqlwinf19.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.6.1.1. Notes</td>
      </tr>
        </table>
</li>
    </ol>
    <p>
      <strong>Displaying Images and Web Pages</strong>
    </p>
<p>Next we will modify the form so that item identified as images or web pages will be opened in a
browser window. Again we will do this by adding a button beside the box on the form that will open the
browser window.
</p>
<ol>
      <li>Add a new class, OpenButton that extends System.Windows.Forms.Button.
<ul>
  <li>In the <strong>Solution Explorer</strong> right click on the RDFDemo project and select
<strong>Add</strong> then <strong>New Item</strong>
</li>
   <li>Add a new class called OpenButton.cs.
</li>
   <li>The following using statement goes at the top of the file:
<div>
              <pre class="programlisting">
using System.Windows.Forms;
</pre>
            </div>
</li>
   <li>The OpenButton class must inherit from System.Windows.Forms.Button so the class
definition line should look like this:
<div>
              <pre class="programlisting">
class OpenButton : Button
</pre>
            </div>
</li>
   <li>Add the following code to the body of the OpenButton class:
<div>
              <pre class="programlisting">
String urlText;

public OpenButton(String text)
{
    urlText = text;
    this.Text = &quot;Open&quot;;
}

protected override void  OnClick(EventArgs e)
{
    System.Diagnostics.Process.Start(urlText);
}
</pre>
            </div>
</li>
</ul>
</li>
      <li>In displayData in the ExtendedStringHandler class, where we added the code to check for long
text fields we now need to check for IRIs that identify images and web pages. As a simple first attempt
we will check for matching labels. So for example, if a property label is &#39;image&#39; or &#39;webpage&#39;, we will
assume it can be opened in a browser window and put an OpenButton beside it.
<div>
          <pre class="programlisting">
if (labelList[i].Text == &quot;website&quot;
    || labelList[i].Text == &quot;image&quot;
    || labelList[i].Text == &quot;depiction&quot;
    || labelList[i].Text == &quot;page&quot;
    || labelList[i].Text == &quot;url&quot;
    || labelList[i].Text == &quot;image skyline&quot;)
{
    openButtonList.Add(new OpenButton(textBoxList[i].DataBindings[0].DataSource.ToString()));
    openButtonList[openButtonList.Count - 1].Location = new Point (550, i * 22 + 50);
    describeForm.Controls.Add(openButtonList[openButtonList.Count - 1]);
}
</pre>
        </div>
</li>
      <li>We will also need a list to hold the buttons as they are created so the following needs to
be added to the member variables at the top of the ExtendedStringHandler class.
<div>
          <pre class="programlisting">
List&lt;OpenButton&gt; openButtonList = new List&lt;OpenButton&gt;();
</pre>
        </div>
</li>
      <li>Build and run the application. If you click through to an Employee page now you will see that
the Image field now has a button labeled Open next to it. If you click on that button the image is opened
in your default browser.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Image" src="../images/ui/sparqlwinf20.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.6.1.1. Image</td>
      </tr>
        </table>
</li>
    </ol>
    <p>
      <strong>Next Steps</strong>
    </p>
<p>It has already been mentioned that the property labels are also dereferenceable IRIs. We used this
feature to find a short name to display rather that the complete IRI. The next step is to make the labels
clickable so the ontology itself can also be explored.
</p>
    <br />
    <br />


    
      <a name="installwfasxtendproplab" />
    <h3>2.9.7. Extending RDFDemo To Make The Property Labels Clickable</h3>
<p>This section will guide you through extending RDFDemo to make the property labels clickable. Clicking
on the property label will take you to a page describing that property.
</p>
<p>
      <strong>Pre-requisites</strong>
    </p>
<ol>
    <li>A working copy of the RDFDemo application created in
<a href="installwfas.html#installwfasxtendlongtext">Extending RDFDemo to Display Images and Longer Text Fields</a>
    </li>
    </ol>
    
      <a name="installwfasxtendproplabmod" />
    <h4>2.9.7.1. Modifying the Application</h4>
    <p>
      <strong>Making the Labels Clickable</strong>
    </p>
<p>Making the property labels clickable is fairly straight forward. We will use basically the same code
as is used to make the values clickable.
</p>
<ol>
      <li>First we need to add a new event handler. In the ExtendedStringHandler class modify displayData
to add an event handler for each of the property labels.
<div>
          <pre class="programlisting">
for (int i = 0; i &lt; table1.Rows.Count; i++)
{
    textBoxList[i].Click += new EventHandler(this.iri_Click);
    labelList[i].Location = new Point(10, i * 22 + 50);
    textBoxList[i].Location = new Point(150, i * 22 + 50);
    describeForm.Controls.Add(labelList[i]);
    describeForm.Controls.Add(textBoxList[i]);
</pre>
        </div>
<p>becomes
</p>
<div>
          <pre class="programlisting">
for (int i = 0; i &lt; table1.Rows.Count; i++)
{
    textBoxList[i].Click += new EventHandler(this.iri_Click);
    labelList[i].Location = new Point(10, i * 22 + 50);
    labelList[i].Click += new EventHandler(this.label_Click);
    textBoxList[i].Location = new Point(150, i * 22 + 50);
    describeForm.Controls.Add(labelList[i]);
    describeForm.Controls.Add(textBoxList[i]);
</pre>
        </div>
</li>
      <li>Then we need to add the EventHandler method. Add the following to the ExtendedStringHandler Class:
<div>
          <pre class="programlisting">
public void label_Click(object sender, EventArgs e)
  {
      int labelNum = 0;

      for (int i = 0; i &lt; labelList.Count; i++)
      {
          if (sender == labelList[i])
          {
              labelNum = i;
              break;
          }
      }

      Object o = describeDataSet.DataTable1.Rows[labelNum][0];
      if (o is SqlExtendedString)
      {
          SqlExtendedString se = (SqlExtendedString)o;
          ExtendedStringHandler seHandler = new ExtendedStringHandler(se, ParentConnection);
          seHandler.displayData();
      }
      else if (o is SqlRdfBox)
      {
          //doesn&#39;t do anything at the moment
      }
  }
</pre>
        </div>
<p>
If you compare this method to the EventHandler for the values, iri_Click, you will see that it is basically
the same. The only difference is that it uses the property element from the data table rather than value.
</p>
</li>
      <li>Finally, to make it clear that the labels are now active links, we will change the label colour
to blue and underline them.
<div>
          <pre class="programlisting">
 propertyLabel.Text = getLabelText(row[0]);
 propertyLabel.AutoEllipsis = true;
 propertyLabel.AutoSize = false;
 propertyLabel.Width = 130;
 propertyLabel.TextAlign = ContentAlignment.MiddleRight;
</pre>
        </div>
<p>becomes:
</p>
<div>
          <pre class="programlisting">
propertyLabel.Text = getLabelText(row[0]);
propertyLabel.ForeColor = Color.Blue;
propertyLabel.Font = new Font(propertyLabel.Font.FontFamily, propertyLabel.Font.Size, propertyLabel.Font.Style | FontStyle.Underline, propertyLabel.Font.Unit);
propertyLabel.AutoEllipsis = true;
propertyLabel.AutoSize = false;
propertyLabel.Width = 130;
propertyLabel.TextAlign = ContentAlignment.MiddleRight;
</pre>
        </div>
</li>
      <li>Build and run the application. You will see the familiar starting page. If you then select one
of the Customers you will notice the property labels now look like hyperlinks.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="hyperlinks" src="../images/ui/sparqlwinf21.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.7.1.1. hyperlinks</td>
      </tr>
        </table>
<p>If you click on one of the label hyperlinks you will see a new form showing detailed information about
the property which can itself be explored further by clicking on labels and values.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
       <tr>
        <td>
                <img alt="labels and values" src="../images/ui/sparqlwinf22.png" />
        </td>
       </tr>
       <tr>
              <td>Figure: 2.9.7.1.1. labels and values</td>
       </tr>
          </table>
</p>
</li>
    </ol>
<p>These simple changes work up to a point but are not robust. If you explore the properties used by the
local Northwind graph you quickly find that the property details are not found. The application needs some
further changes to work consistently. The problem is finding the graph where the property information is
defined. The general handler for Extended Strings first checks the local Northwind graph,
http://localhost:8890/Northwind, where the Northwind data is held, and then uses the IRI itself as the graph
and tries to load that dynamically. This is not working for information about the Northwind properties.
These properties are defined in the Northwind ontology, http://demo.openlinksw.com/schemas/northwind. We
have already had to find this graph when getting the short label name. We need to be able to associate the
property label with the graph where its definition is stored. Then we can search this graph for details
about the property when the label is clicked.
</p>
    <p>
      <strong>Using the Graph Where the Property Label was Found to Find the Property Details</strong>
    </p>
<ol>
      <li>Create a new class, IRILabel, that inherits from System.Windows.Forms.Label.
<ul>
  <li>In the <strong>Solution Explorer</strong> right click on the RDFDemo project and select
<strong>Add</strong> then <strong>New Item</strong>.</li>
  <li>Add a new class called IRILabel.cs.
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
        <tr>
         <td>
                  <img alt="Add a new class" src="../images/ui/sparqlwinf23.png" />
         </td>
        </tr>
        <tr>
                <td>Figure: 2.9.7.1.1. Add a new class</td>
        </tr>
            </table>
</li>
</ul>
</li>
      <li>We need to reference System.Windows.Forms, System.Data and OpenLink.Data.Virtuoso so add
<div>
          <pre class="programlisting">
using System.Windows.Forms;
using OpenLink.Data.Virtuoso;
using System.Data;
</pre>
        </div>
<p>to the using block at the top of the class file. The class definition should look like this:
</p>
<div>
          <pre class="programlisting">
class IRILabel : Label
</pre>
        </div>
</li>
      <li>Paste the following code into the body of the class:
<div>
          <pre class="programlisting">
SqlExtendedString SourceIRI;
String GraphUsed;
VirtuosoConnection ParentConnection;

public IRILabel(Object iri, List&lt;String&gt; graphList, VirtuosoConnection parentConnection)
{
    ParentConnection = parentConnection;
    if (iri is SqlExtendedString)
    {
        SourceIRI = (SqlExtendedString)iri;
        Text = this.getLabelText(graphList);
    }
    else
        Text = iri.ToString();
}

public SqlExtendedString iri
{
    get
    {
        return SourceIRI;
    }
}

public String graph
{
    get
    {
        return GraphUsed;
    }
}

private string getLabelText(List&lt;String&gt; graphList)
{
    string labelText = SourceIRI.ToString();
    Boolean foundLabel = false;
    VirtuosoDataAdapter getLabelAdapter = new VirtuosoDataAdapter();
    DataSet getLabelDataSet = new DataSet();

    //Try finding it in resources graph first
    foreach (String graph in graphList)
    {
        StringBuilder getLabelCommandText = new StringBuilder(&quot;sparql select * from &lt;&quot; + graph + &quot;&gt; where {&lt;&quot; + SourceIRI.ToString() + &quot;&gt; ?p ?o}&quot;);
        VirtuosoCommand getLabelCommand = new VirtuosoCommand(getLabelCommandText.ToString(), ParentConnection);
        getLabelAdapter.SelectCommand = getLabelCommand;

        try
        {
            getLabelAdapter.Fill(getLabelDataSet);
            foreach (DataRow getLabelRow in getLabelDataSet.Tables[0].Rows)
            {
                if (getLabelRow[0].ToString() == &quot;http://www.w3.org/2000/01/rdf-schema#label&quot;)
                {
                    labelText = getLabelRow[1].ToString();
                    foundLabel = true;
                    break;
                }
            }
        }
        catch
        {
        }
        if (foundLabel)
        {
            GraphUsed = graph;
            break;
        }
    }

    // If we still have no label try the predicate itself as the graph
    if (!foundLabel)
    {
        GraphUsed = SourceIRI.ToString();
        StringBuilder getLabelCommandText = new StringBuilder(&quot;sparql define get:soft \&quot;soft\&quot; select * from &lt;&quot; + GraphUsed + &quot;&gt; where {&lt;&quot; + SourceIRI.ToString() + &quot;&gt; ?p ?o}&quot;);
        VirtuosoCommand getLabelCommand = new VirtuosoCommand(getLabelCommandText.ToString(), ParentConnection);
        getLabelAdapter.SelectCommand = getLabelCommand;
        try
        {
            getLabelAdapter.Fill(getLabelDataSet);
            foreach (DataRow getLabelRow in getLabelDataSet.Tables[0].Rows)
            {
                if (getLabelRow[0].ToString() == &quot;http://www.w3.org/2000/01/rdf-schema#label&quot;)
                {
                    labelText = getLabelRow[1].ToString();
                    break;
                }
            }
        }
        catch
        {
        }
    }
    return labelText;
}
</pre>
        </div>
<p>Notice that the getLabelText method has been moved into this new class and is now called from the
constructor. When the IRILabel is constructed the label text is found using the list of graphs provided to
the constructor. The graph containing the label is noted. We need to alter ExtendedStringHandler so that
the labels are the new IRILabel type and so that the correct information is supplied to the constructor.
</p>
  </li>
      <li>Change the labelList member variable declaration so it looks like this:
<div>
          <pre class="programlisting">
List&lt;IRILabel&gt; labelList = new List&lt;IRILabel&gt;();
</pre>
        </div>
  </li>
      <li>Each propertyLabel created must be the new IRILabel type so the line:
<div>
          <pre class="programlisting">
Label propertyLabel = new Label();
</pre>
        </div>
<p>becomes:
</p>
<div>
          <pre class="programlisting">
IRILabel propertyLabel = new IRILabel(row[0], graphList, ParentConnection);
</pre>
        </div>
  </li>
      <li>As getLabelText is now called by the IRILabel constructor we can remove the line:
<div>
          <pre class="programlisting">
propertyLabel.Text = getLabelText(row[0]);
</pre>
        </div>
<p>from describeData in ExtendedStringHandler.
</p>
  </li>
      <li>Now we modify the label_Click EventHandler so that it uses the graph information. Replace the
existing method with:
<div>
          <pre class="programlisting">
public void label_Click(object sender, EventArgs e)
  {
      int labelNum = 0;

      for (int i = 0; i &lt; labelList.Count; i++)
      {
          if (sender == labelList[i])
          {
              labelNum = i;
              break;
          }
      }

      SqlExtendedString se = labelList[labelNum].iri;
      ExtendedStringHandler seHandler = new ExtendedStringHandler(se, ParentConnection, labelList[labelNum].graph);
          seHandler.displayData();

  }
</pre>
        </div>
  </li>
      <li>Note that this method uses a new constructor for the ExtendedStringHandler that takes the graph
as an additional argument. We need to add this new constructor.
<div>
          <pre class="programlisting">
public ExtendedStringHandler(SqlExtendedString iri, VirtuosoConnection parentConnection, String graph)
  {
      ParentConnection = parentConnection;
      if (iri.IriType == SqlExtendedStringType.IRI)
      {
          ParentIRI = iri;
          isIRI = true;
          DescribeCommandSimple = new StringBuilder(&quot;sparql select * from &lt;http://localhost:8890/Northwind&gt; where {&lt;&quot; + iri.ToString() + &quot;&gt; ?p ?o}&quot;);
          DescribeCommandGeneral = new StringBuilder(&quot;sparql define get:soft &quot; + &#39;&quot;&#39;.ToString() + &quot;soft&quot; + &#39;&quot;&#39;.ToString() + &quot; select * from &lt;&quot; + graph + &quot;&gt; where { &lt;&quot; + iri.ToString() + &quot;&gt; ?p ?o }&quot;);
      }
  }
</pre>
        </div>
<p>This new constructor uses the supplied graph to build the alternative sparql select statement that
looks for the details about the supplied IRI. With these changes in place the application will find the
description of the Northwind properties.
</p>
  </li>
      <li>Build and run. As you explore the data you will see that you can find descriptions of the
properties used to describe the entities in the Northwind dataset:
    <table class="figure" border="0" cellpadding="0" cellspacing="0">
      <tr>
       <td>
              <img alt="Northwind dataset" src="../images/ui/sparqlwinf24.png" />
       </td>
      </tr>
      <tr>
            <td>Figure: 2.9.7.1.1. Northwind dataset</td>
      </tr>
        </table>
  </li>
    </ol>
    <br />
    <br />
  <table border="0" width="90%" id="navbarbottom">
    <tr>
        <td align="left" width="33%">
          <a href="installusado.html" title="Using Visual Studio 2008 to Build an ADO.NET Data Services based Application">Previous</a>
          <br />Using Visual Studio 2008 to Build an ADO.NET Data Services based Application</td>
     <td align="center" width="34%">
          <a href="installation.html">Chapter Contents</a>
     </td>
        <td align="right" width="33%">
          <a href="installcrweb.html" title="Creating a Web Browser Application to Access RDF Data Using The Virtuoso ADO.Net Provider">Next</a>
          <br />Creating a Web Browser Application to Access RDF Data Using The Virtuoso ADO.Net Provider</td>
    </tr>
    </table>
  </div>
  <div id="footer">
    <div>Copyright© 1999 - 2009 OpenLink Software All rights reserved.</div>
   <div id="validation">
    <a href="http://validator.w3.org/check/referer">
        <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" />
    </a>
    <a href="http://jigsaw.w3.org/css-validator/">
        <img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" height="31" width="88" />
    </a>
   </div>
  </div>
 </body>
</html>