# Modeling an RDF Resource

The following content highlights the key modifications to a Java class to convert it into an [RDF resource](/reference/glossary.md#rdf-resource) class. As a starting point, consider a non-RDF class **`Expense`**. Such a class may be implemented similarly to the following sample code:

```java
// Non-RDF Class

public class Expense {
    private UUID _id;
    private Date date;
    private String description;
    // ... Additional fields

    public Expense() {

    }

    public Expense(date, description, //...) {

       this.date = date;
       this.description = descriptions;
       //...
    }

    public Date getDate() {
         return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    // ... Additional getters/setters and other content

}
```

### 1. Extend the SolidRDFSource

The [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html) class maps to an RDF resource. A summary of parameters to the [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html) class constructors are as follows:

<table><thead><tr><th width="138.55078125">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>identifier</code></strong></td><td><a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URI.html">java.net.URI</a></td><td>The URI (Uniform Resource Identifier) of the resource.</td></tr><tr><td><strong><code>dataset</code></strong></td><td><a href="https://commons.apache.org/proper/commons-rdf/apidocs/org/apache/commons/rdf/api/Dataset.html">org.apache.commons.rdf.api.Dataset</a></td><td>The RDF dataset (i.e., the sets of triples) contained in the resource.</td></tr><tr><td><strong><code>headers</code></strong></td><td><a href="https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/Headers.html">com.inrupt.client.Headers</a></td><td>Collection of HTTP headers.</td></tr></tbody></table>

To model the **`Expense`** class as an RDF resource, the class:

* Extends the [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html) and
* Adds constructors for the [SolidRDFSource](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/solid/SolidRDFSource.html) fields (**`identifier`**, **`dataset`**, **`headers`**).

```java
public class Expense extends SolidRDFSource {

   private final Node subject;
   // ...

   public Expense(final URI identifier, final Dataset dataset, final Headers headers) {
       super(identifier, dataset, headers);
       // ...
   }

   public Expense(final URI identifier) {
       this(identifier, null, null);
   }

   public Expense(final URI identifier,
                  String merchantProvider,
                  Date expenseDate,
                  String description,
                  BigDecimal amount,
                  String currency,
                  String category) {
       this(identifier, null, null);
       //...
   }
}
```

{% hint style="warning" %}
The SolidRDFSource constructor that accepts Metadata as a parameter (instead of Headers) has been deprecated.
{% endhint %}

### 2. Inner Class that Extends WrapperIRI

A sample RDF file that for a sample Expense data is shown below in [Turtle format](/reference/glossary.md#turtle):

```turtle
<https://pod.example.com/container/expenses/202303/teamlunch>
     <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>   <https://schema.org/Invoice> ;
     <https://schema.org/purchaseDate>    "2023-03-07T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
     <https://schema.org/provider>        "Example Restaurant" ;
     <https://schema.org/description>     "Team Lunch" ;
     <https://schema.org/category>        "Travel and Entertainment" ;
     <https://schema.org/priceCurrency>   "USD" ;
     <https://schema.org/totalPrice>      "120"^^<http://www.w3.org/2001/XMLSchema#decimal> ;
     <https://schema.org/image>           <https://pod.example.com/container/expenses/202303/receipt1.jpg> .
```

where:

<table data-header-hidden><thead><tr><th width="121.48828125"></th><th width="103.29296875"></th><th></th></tr></thead><tbody><tr><td><code>subject</code></td><td>URL</td><td><code>&#x3C;https://pod.example.com/container/expenses/202303/teamlunch></code></td></tr><tr><td><code>predicates</code></td><td>URL</td><td><ul><li><code>&#x3C;http://www.w3.org/1999/02/22-rdf-syntax-ns#type></code></li><li><code>&#x3C;https://schema.org/purchaseDate></code></li><li><code>&#x3C;https://schema.org/provider></code></li><li>etc.</li></ul></td></tr><tr><td><code>objects</code></td><td>Literals or URLS</td><td><ul><li><code>"2023-03-07T00:00:00Z"^^&#x3C;http://www.w3.org/2001/XMLSchema#dateTime></code></li><li><code>"Example Restaurant"</code>,</li><li><code>&#x3C;https://pod.example.com/expenses/receipt1.jpg></code></li><li>etc.</li></ul></td></tr></tbody></table>

To handle the mapping of the expense data (date, provider, description, category, priceCurrency, total) to RDF triples (**`<subject> <predicate> <object>`**):

* The **`Expense`** class defines the predicate IRIs. That is, instead of having a Class field named **`date`**, for the RDF Resource, the value of the field is mapped to the IRI **`"https://schema.org/purchaseDate"`**.
* The **`Expense`** class defines an inner class **`Node`** that extends the [WrapperIRI](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/rdf/wrapping/commons/WrapperIRI.html) class.

```java
public class Expense extends SolidRDFSource {

   // ...
    static IRI SCHEMA_DATE = rdf.createIRI("https://schema.org/purchaseDate");
    static IRI SCHEMA_PROVIDER = rdf.createIRI("https://schema.org/provider");
    static IRI SCHEMA_DESCRIPTION = rdf.createIRI("https://schema.org/description");
    static IRI SCHEMA_TOTAL_PRICE = rdf.createIRI("https://schema.org/totalPrice");
    static IRI SCHEMA_CURRENCY = rdf.createIRI("https://schema.org/priceCurrency");
    static IRI SCHEMA_CATEGORY = rdf.createIRI("https://schema.org/category");
    static IRI SCHEMA_IMAGE = rdf.createIRI("https://schema.org/image");

    // ...

    class Node extends WrapperIRI {

       Node(final RDFTerm original, final Graph graph) {
           super(original, graph);
       }

       URI getRDFType() {
           return anyOrNull(RDF_TYPE, ValueMappings::iriAsUri);
       }

       void setRDFType(String type) {
           overwriteNullable(RDF_TYPE, type, TermMappings::asIri);
       }

       String getMerchantProvider() {
           return anyOrNull(SCHEMA_PROVIDER, ValueMappings::literalAsString);
       }


      String getMerchantProvider() {
          return anyOrNull(SCHEMA_PROVIDER, ValueMappings::literalAsString);
      }

      void setMerchantProvider(String provider) {
          overwriteNullable(SCHEMA_PROVIDER, provider, TermMappings::asStringLiteral);
      }

      // ...

    }
}
```

### Add the Inner Class Field to the RDF Resource Class

To use the defined mappings in the inner class:

* Update **`Expense.java`** to include a new field **`subject`** set to the inner class **`Node`**.
* Update the **`Expense.java`** getters and setters to use the **`subject`**‘s getters and setters.

```java
public class Expense extends SolidRDFSource {

   // ...


    private final Node subject;

    // ...

    public URI getRDFType() {
        return subject.getRDFType();
    }

    public void setRdfType(String rdfType) {
        subject.setRDFType(rdfType);
    }

    public String getMerchantProvider() {
        return subject.getMerchantProvider();
    }

    public void setMerchantProvider(String merchantProvider) {
        subject.setMerchantProvider(merchantProvider);
    }

    public Date getExpenseDate() {
        return subject.getExpenseDate();
    }

    public void setExpenseDate(Date expenseDate) {
        subject.setExpenseDate(expenseDate);
    }

    //...

}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.inrupt.com/sdk/java-sdk/crud-rdf-data/modeling-rdf-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
