Step 5: Add receipt.png
You can use the Java Client Libraries to save non-RDF resources (e.g., .png
, .pdf
) to your Pod.
For this part of the tutorial, the getting started app uses Inrupt’s Java client library to:
Store a copy of the expense receipts to your Pod.
Update the associated expense to link to the URLs of the receipts.
Update application.properties
application.properties
Add the following properties to the src/main/resources/application.properties
file:
spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
Modify Expense
Class
Expense
ClassOpen
Expense
class file:
Open src/main/java/com/example/gettingstarted/Expense.java
Add the
java.util.*
import statement:
import java.util.*;
Add the predicate definition for the receipts in the
Expense
class:
static IRI SCHEMA_ORG_IMAGE = rdf.createIRI("https://schema.org/image");
Update the
Expense
class constructor to include the receipts:
@JsonCreator
public Expense(@JsonProperty("identifier") final URI identifier,
@JsonProperty("merchantProvider") String merchantProvider,
@JsonProperty("expenseDate") Date expenseDate,
@JsonProperty("description") String description,
@JsonProperty("amount") BigDecimal amount,
@JsonProperty("currency") String currency,
@JsonProperty("category") String category,
@JsonProperty("receipts") String[] receipts) {
this(identifier);</strong>
this.setRDFType(MY_RDF_TYPE_VALUE);
this.setMerchantProvider(merchantProvider);
this.setExpenseDate(expenseDate);
this.setDescription(description);
this.setAmount(amount);
this.setCurrency(currency);
this.setCategory(category);
this.setReceipts(receipts);
}
Add the getter and setters for the receipts in the
Expense
class:
public Set<String> getReceipts() {
return subject.getReceipts();
}
// Note:: The setters first uses the getter, which returns a Set, and adds the receipt to the set.
public void addReceipt(String receipt) {
subject.getReceipts().add(receipt);
}
public void setReceipts(String[] receipts) {
subject.getReceipts().addAll(List.of(receipts));
}
Add getter for the receipts in the inner
Node
class:
public Set<String> getReceipts() {
return objects(SCHEMA_ORG_IMAGE, TermMappings::asIri, ValueMappings::iriAsString);
}
Modify ExpenseController
Class
ExpenseController
ClassOpen
ExpenseController
class file.
Open src/main/java/com/example/gettingstarted/ExpenseController.java
Add the following import statements:
import com.inrupt.client.solid.SolidNonRDFSource;
import org.springframework.web.multipart.MultipartFile;
Add the following method to handle the upload of non-RDF files:
/**
* Note 9: Stores a non-RDF resource to a Pod
*
* Using SolidNonRDFSource and the SolidSyncClient .create() method,
* - Saves a non-RDF resource at the destinationURL.
*/
@PutMapping("**/resource/nonRDF/add**")
public String addNonRDFFile(@RequestParam(value = "destinationURL") String destinationURL,
@RequestParam(value = "file") MultipartFile file) {
printWriter.println("In addNonRDFFile:: Save Non-RDF File to Pod.");
try (final var fileStream = file.getInputStream()) {
SolidNonRDFSource myNonRDFFile = new SolidNonRDFSource(URI.create(destinationURL), file.getContentType(), fileStream);
return client.create(myNonRDFFile).getIdentifier().toString();
} catch(PreconditionFailedException e1) {
// Errors if the resource already exists
printWriter.println(String.format("[%s] com.inrupt.client.solid.PreconditionFailedException in addNonRDFFile:: %s", e1.getStatusCode(), e1.getMessage()));
} catch(ForbiddenException e2) {
// Errors if user does not have access to create
printWriter.println(String.format("[%s] com.inrupt.client.solid.ForbiddenException in addNonRDFFile:: %s", e2.getStatusCode(), e2.getMessage()));
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
Add the following method that uploads a receipt file and links it to the associated
Expense
.
/**
* Note 10: Stores a non-RDF resource (image of the receipt) to a Pod and Attach to an Expense
* Using methods defined as part of getting started, addReceiptToExpense:
* - Calls addNonRDFFile() to store the receipt to a Pod
* - Calls getExpense() to fetch the associated Expense RDF resource.
* - Calls the Expense's setter `addReceipt` to add the link to the saved receipt.
* - Calls updateExpense() to save the updated Expense.
*/
@PutMapping("**/expenses/receipts/add**")
public Expense addReceiptToExpense(@RequestParam(value = "destinationURL") String destinationURL,
@RequestParam(value = "file") MultipartFile file,
@RequestParam(value = "expenseURL") String expenseURL) {
printWriter.println("In addReceiptToExpense: Save Receipt File to Pod and Update Associated Expense.");
try {
String receiptLocation = addNonRDFFile(destinationURL, file);
if (receiptLocation != null) {
Expense expense = getExpense(expenseURL);
expense.addReceipt(receiptLocation);
return updateExpense(expense);
} else {
printWriter.println("Error adding receipt");
return null;
}
} catch(ForbiddenException e2) {
// Errors if user does not have access to read or update the Expense resource
printWriter.println(String.format("[%s] com.inrupt.client.solid.ForbiddenException in addReceiptToExpense:: %s", e2.getStatusCode(), e2.getMessage()));
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
Last updated