Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat (core): RDF Loader now directly creates strongly typed Thing objects #1206

Merged
merged 1 commit into from
Mar 9, 2025

Conversation

vorburger
Copy link
Member

No description provided.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @vorburger, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

This pull request focuses on enhancing the RDF loader to directly create strongly typed Thing objects. It modifies the RdfResourceIntoThingConverter to identify type IRIs from the proto Thing and use them when creating Thing builders. A new test case is added to verify that loading an RDF resource results in an instance of the expected Java class, not just a generic Thing. Additionally, the copyright year in VersionProvider.java is updated to include 2025.

Highlights

  • Strongly Typed Thing Creation: The RDF loader now creates strongly typed Thing objects directly, leveraging type IRIs found in the RDF data.
  • Type IRI Extraction: The RdfResourceIntoThingConverter extracts type IRIs from proto Thing objects to guide the creation of specific Thing builders.
  • New Test Case: A new test case testSomething() verifies that loading RDF data results in an instance of the expected Java class, ensuring proper type handling.
  • Copyright Update: The copyright year in VersionProvider.java has been updated to include 2025.

Changelog

Click here to see the changelog
  • java/dev/enola/cli/common/VersionProvider.java
    • Updated the copyright year to 2023-2025.
  • java/dev/enola/rdf/io/RdfResourceIntoThingConverter.java
    • Added import for dev.enola.thing.java.HasType.
    • Added import for @Nullable annotation.
    • Modified the convertInto method to check for a type IRI in the proto Thing.
    • If a type IRI is found, the getBuilder method is called with the type IRI to create a strongly typed Thing builder.
    • Added a private typeIRI method to extract the type IRI from the proto Thing.
  • java/dev/enola/rdf/io/RdfResourceIntoThingConverterTest.java
    • Added imports for dev.enola.thing.impl.ImmutableThing, dev.enola.thing.java.ProxyTBF, and dev.enola.thing.java.test.TestSomething.
    • Added a new test case testSomething() to load testSomething.ttl and verify that it's an instance of TestSomething.
    • Modified the convert method to use ThingsBuilders with ProxyTBF.
  • java/dev/enola/thing/java/RdfAnnotations.java
    • Added a TODO comment to cache the results of Class.getAnnotation() to improve performance.
  • java/dev/enola/thing/repo/ThingsBuilders.java
    • Deprecated the default constructor ThingsBuilders() and added a comment to remove it, suggesting replacement with ThingsBuilders(TBF tbf).
    • Added a new getBuilder method that takes a thingIRI and typeIRI to create a Thing.Builder for a specific type.
    • Modified the existing getBuilder method to use thingIRI instead of iri.
  • test/testSomething.ttl
    • Added a new test file testSomething.ttl containing RDF data for a TestSomething instance.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


Trivia time!

What is the purpose of RDF's 'a' predicate?

Click here for the answer
In RDF, the predicate 'a' is shorthand for `rdf:type`. It's used to assert that a resource is an instance of a particular class.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant enhancement by enabling the RDF loader to directly create strongly typed Thing objects. This is achieved by inspecting the RDF data for type information and using it to instantiate the appropriate Java class for the Thing. The changes include modifications to RdfResourceIntoThingConverter, ThingsBuilders, and the addition of a test case to verify the correct instantiation of TestSomething. Overall, the changes look good, but there are a few areas that could be improved.

Summary of Findings

  • TODO comment in RdfAnnotations.java: The RdfAnnotations class contains a TODO comment indicating that the results of Class.getAnnotation() should be cached to improve performance. This should be addressed.
  • Deprecated constructor in ThingsBuilders.java: The ThingsBuilders class has a deprecated constructor that should be removed once all usages are migrated to the constructor that accepts a TBF.
  • Missing null check: In RdfResourceIntoThingConverter.java, the value obtained from protoThing.getPropertiesMap().get(HasType.IRI) is checked for null, but the result of value.hasLink() is not. This could lead to a NullPointerException if value is not null but value.hasLink() is called on a null object.

Merge Readiness

The pull request is almost ready for merging. However, the TODO comment in RdfAnnotations.java should be addressed, and the deprecated constructor in ThingsBuilders.java should be removed. Additionally, a null check should be added in RdfResourceIntoThingConverter.java to prevent a potential NullPointerException. Once these issues are resolved, the pull request should be ready for merging. I am unable to approve this pull request, and other reviewers should review and approve this code before merging.


private @Nullable String typeIRI(dev.enola.thing.proto.Thing.Builder protoThing) {
var value = protoThing.getPropertiesMap().get(HasType.IRI);
if (value != null && value.hasLink()) return value.getLink();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Consider adding a null check for value.hasLink() to avoid a potential NullPointerException if value is not null but doesn't have a link.

Suggested change
if (value != null && value.hasLink()) return value.getLink();
if (value != null && value.hasLink() && value.getLink() != null) return value.getLink();

@@ -24,6 +24,8 @@

public class RdfAnnotations {

// TODO Cache these! Because repeated Class.getAnnotation() is quite expensive.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's good that you've identified this as a potential performance bottleneck. Consider implementing a caching mechanism (e.g., using Guava's CacheBuilder) to store the results of Class.getAnnotation() for frequently accessed classes. This will reduce the overhead of repeated reflection calls.

Comment on lines +49 to 51
@Deprecated // TODO Remove ThingsBuilders() by replacing with ThingsBuilders(TBF tbf)
public ThingsBuilders() {
this(ImmutableThing.FACTORY);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since this constructor is deprecated, ensure that all usages are migrated to the constructor that accepts a TBF. Once all usages are migrated, remove this constructor to avoid confusion.

@vorburger vorburger merged commit 93f0dac into enola-dev:main Mar 9, 2025
9 checks passed
@vorburger vorburger deleted the iri5 branch March 9, 2025 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant