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

Ability to use an opaque namespace? #19

Closed
bpfoster opened this issue Sep 13, 2012 · 3 comments
Closed

Ability to use an opaque namespace? #19

bpfoster opened this issue Sep 13, 2012 · 3 comments
Labels

Comments

@bpfoster
Copy link

First I must say that after experimenting with other JSON libraries I am thoroughly impressed with this project, and thank you for it. It's simple to use and works great.

Is there a way that I'm missing, or do you have any thoughts on having an opaque namespace for schemas? I hate to talk to generics, so here's the specific use case -
Our schemas $ref each other with relative links - in this case all sit inside a folder. That folder is packaged inside the jar. I then create the factory and set the namespace similar to:

new JsonSchemaFactory.Builder().setNamespace(getClass().getResource("/schemas/").toURI().toASCIIString()).build();

Unfortunately, during validation this fails, because of the line in SchemaRegistry.get():

realURI = namespace.resolve(uri).normalize();

Because namespace is an opaque URI in this case (jar:file:/<path>!/schemas/), the Java URI API simply returns the value of the uri parameter.

A simple hack I've done to get around it is to change SchemaRegistry and basically concat namespace + uri, but I wanted to see if there was a more elegant way to do this, or a reason why not.

Thanks for the feedback.

@fge
Copy link
Collaborator

fge commented Sep 13, 2012

Hello,

First, thank you for the appreciative comments!

There is a hack in the code, in JsonRef, so as to deal specifically with jar URIs, so it seems it is not plugged where you expect. Hmm. I'll have to devise a test.

I have two questions:

  1. how do you define an opaque URI? I have always had trouble with that;
  2. is your jar in the classpath? If yes, can't you use:
// Note the final /
new JsonSchemaFactory.Builder().setNamespace("resource:/base/path/to/schemas/")

?

@bpfoster
Copy link
Author

Aha! - I knew I had to be missing something stupid simple. Yes, using a resource:/path/to/schemas/ namespace works perfectly for this! Thank you!

I will admit that the idea of an opaque URI was new to me when starting this, so I have to rely on the Javadoc:

An opaque URI is an absolute URI whose scheme-specific part does not begin with a slash character ('/')

vs a hierarchical:

A hierarchical URI is either an absolute URI whose scheme-specific part begins with a slash character, or a relative URI, that is, a URI that does not specify a scheme

So in this case we have 2 URIs: jar:file:/path/to/jarfile!/path/inside/jar/ , and resource:/path/inside/jar/. Based on the documentation, I take it to mean the scheme in the first is jar: and the second is resource:. The next character (beginning the 'scheme-specific part'), respectively, is f and /, thus making the first opaque and the second hierarchical.

Thank you so much for the quick pointer!

@fge
Copy link
Collaborator

fge commented Sep 13, 2012

Glad to know it worked!

However, I still think there is a bug. You can, indeed, do:

final JsonSchema schema = factory.fromURI("jar:file:/foo/bar.jar!/path/to/schema");

and, in this case, $ref will also work. Setting a "jar" namespace and loading a schema, however, will not.

I have to think abouti it some more.

fge added a commit that referenced this issue Sep 13, 2012
The test which breaks is due to a difference in behavior between:

    factory = JsonSchemaFactory.defaultFactory();
    schema = factory.fromURI("jar:/foo.jar!/a/b.json");

and:

    factory = new JsonSchemaFactory.Builder()
        .setNamespace("jar:/foo.jar!/a/").build();
    schema = factory.fromURI("b.json");

While the first solution will use the base URIDownloader and succeed, the second
one will fail since SchemaRegistry does not use JsonRef, which has a hack for
jar relative resolution, but URI resolution -- and resolving any URI against an
opaque URI, which "jar" URIs are, leads to the URI given as an argument.

First highlighted in issue #19.

Signed-off-by: Francis Galiegue <fgaliegue@gmail.com>
fge added a commit that referenced this issue Sep 14, 2012
Probably the last 1.1.x release.

* Rework JsonRef. This fixes bugs #19, #20.
* Rename FormatSpecifier to FormatAttribute.
* Javadoc updates. In particular, mention the "id" conundrum, and why this
  implementation chooses to ignore section 5.27.

Francis Galiegue (16):
      M{in,ax}PropertiesKeywordValidator: fix javadoc
      Large renaming: format specifier --> format attribute
      Add skeleton test file for opaque namespace testing
      JarNamespaceValidationTest: test that one scenario works
      JarNamespaceValidationTest: improve code
      JarNamespaceValidationTest: devise test which does not work, but should
      "Fix" issue #20, the ugly way
      Introduce JsonLocator class and implementations, plus tests
      JsonRef: rename .asURI() to .toURI()
      More tests to catch malformed "jar" URLs
      JsonRef: method rename
      Rework JsonRef
      Remove JsonLocator, now unneeded
      JsonRef: simplify code a little
      Inspections pass, some nitpicks fixed
      Various Javadoc updates

Signed-off-by: Francis Galiegue <fgaliegue@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants