Git Product home page Git Product logo

halbuilder-core's People

Contributors

glaforge avatar huwtl avatar jcassee avatar jogura-zz avatar jpommerening avatar kevinsawicki avatar slovdahl avatar talios avatar tedyoung avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

halbuilder-core's Issues

Dalvikvm: Could not find method java.beans.Introspector.getBeanInfo

On Android 4.4 the library does not work, it crashes with the following trace error:

02-12 15:05:59.842 14367-15000/ro.assist.bookingbugandroid I/dalvikvm: Could not find method java.beans.Introspector.getBeanInfo, referenced from method com.theoryinpractise.halbuilder.impl.representations.MutableRepresentation.withBean
02-12 15:05:59.842 14367-15000/ro.assist.bookingbugandroid W/dalvikvm: VFY: unable to resolve static method 46929: Ljava/beans/Introspector;.getBeanInfo (Ljava/lang/Class;)Ljava/beans/BeanInfo;
02-12 15:05:59.842 14367-15000/ro.assist.bookingbugandroid D/dalvikvm: VFY: replacing opcode 0x71 at 0x0004
02-12 15:05:59.852 14367-15000/ro.assist.bookingbugandroid W/dalvikvm: VFY: unable to resolve exception class 5409 (Ljava/beans/IntrospectionException;)
02-12 15:05:59.852 14367-15000/ro.assist.bookingbugandroid W/dalvikvm: VFY: unable to find exception handler at addr 0x33
02-12 15:05:59.852 14367-15000/ro.assist.bookingbugandroid W/dalvikvm: VFY: rejected Lcom/theoryinpractise/halbuilder/impl/representations/MutableRepresentation;.withBean (Ljava/lang/Object;)Lcom/theoryinpractise/halbuilder/api/Representation;
02-12 15:05:59.852 14367-15000/ro.assist.bookingbugandroid W/dalvikvm: VFY: rejecting opcode 0x0d at 0x0033
02-12 15:05:59.852 14367-15000/ro.assist.bookingbugandroid W/dalvikvm: VFY: rejected Lcom/theoryinpractise/halbuilder/impl/representations/MutableRepresentation;.withBean (Ljava/lang/Object;)Lcom/theoryinpractise/halbuilder/api/Representation;
02-12 15:05:59.852 14367-15000/ro.assist.bookingbugandroid W/dalvikvm: Verifier rejected class Lcom/theoryinpractise/halbuilder/impl/representations/MutableRepresentation;
02-12 15:05:59.862 14367-15000/ro.assist.bookingbugandroid W/dalvikvm: threadid=11: thread exiting with uncaught exception (group=0x41c96d58)
02-12 15:05:59.952 14367-15000/ro.assist.bookingbugandroid E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: ro.assist.bookingbugandroid, PID: 14367
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.VerifyError: com/theoryinpractise/halbuilder/impl/representations/MutableRepresentation
at helpers.hal_addon.CustomJsonRepresentationReader.readResource(CustomJsonRepresentationReader.java:51)
at helpers.hal_addon.CustomJsonRepresentationReader.read(CustomJsonRepresentationReader.java:44)
at com.theoryinpractise.halbuilder.DefaultRepresentationFactory.readRepresentation(DefaultRepresentationFactory.java:96)
at bookingbugAPI.services.HttpService.callApi(HttpService.java:198)
at bookingbugAPI.services.HttpService.callApi(HttpService.java:135)
at bookingbugAPI.services.HttpService.api_POST(HttpService.java:103)
at bookingbugAPI.models.BBRoot.auth(BBRoot.java:69)
at ro.assist.bookingbugandroid.data.tasks.AdminLogin.doInBackground(AdminLogin.java:59)
at ro.assist.bookingbugandroid.data.tasks.AdminLogin.doInBackground(AdminLogin.java:14)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:841) 

JsonRender needs a Codec set

        f.setCodec(new ObjectMapper());

Update the JSON renderer to use ObjectMapper to serialize out arrays, and on the Reader to read in arrays.

Also look at how to handle this on XML?

Please update maven

Could you please push the latest version to maven?
I ran into a bug at DefaultRepresentationFactory.lookupRenderer(String contentType). The mediatype does not get parsed correctly, after properly removing the "application/" prefix it tries to match the subtypes "hal+json;charset=utf-8" with "hal+json", which of course aren't equal.
The function seems to have gotten a major overhaul and should work, but there are only old versions on maven. I'll try to get the ";charset=utf-8" postfix removed on my side, but I'd really prefer to just use the latest Halbuilder.

Ability for per link relationship single element array setting

Currently, when using halbuilder-json, I can only specify a global setting for whether to serialize single element arrays as arrays or items for _links/_embedded.

For my use case, I would like to be able to have single elements arrays treated as just the item for links, but for a specific embedded resource link relation, always serialize it as an array, even with only element.

As far as API, I could see:

  1. An overload of withRepresentation with a parameter to specify always being an array: repFactory.newRepresentation().withRepresentation('orders', myOrder, true)
  2. Settings for a representation instance: repFactory.newRepresentation().setArrayRelationship('orders')
  3. Settings for specific link relations in the RepresentationFactory, e.g: repFactory.withArrayRelationship('orders')

Thoughts?

NPE while printing empty representation

In the follow code the print(...) method throws NPE when try to get the type of the tree.

        ResourceRepresentation<Void> empty = ResourceRepresentation.empty();
        JsonRepresentationWriter writer = JsonRepresentationWriter.create();
        ByteString jsonBS = writer.print(empty);
        System.out.println(jsonBS.utf8());

The empty resource should be printed into {} string. This would be empty JSON document.

On another hand because empty JSON is not valid HAL document I guess factory call ResourceRepresentation.empty() should not be allowed.

The same problem exists even of I provide href for self link. So any call to empty(...) produces invalid ResourceRepresentation instance.

IllegalArgumentException thrown if MediaType contains Relative Quality Factors

When the content type {application/hal+json;q=1000} is passed in the request header it does not "match" any ContentType in the DefaultRepresentationFactory.lookupRenderer() method.

The result is:

! java.lang.IllegalArgumentException: Unsupported contentType: {application/hal+json, q=1000}
! at com.theoryinpractise.halbuilder.DefaultRepresentationFactory.lookupRenderer(DefaultRepresentationFactory.java:116) ~[halbuilder-core-4.0.3.jar:na]
! at com.theoryinpractise.halbuilder.impl.representations.BaseRepresentation.toString(BaseRepresentation.java:295) ~[halbuilder-core-4.0.3.jar:na]
! at com.theoryinpractise.halbuilder.impl.representations.BaseRepresentation.toString(BaseRepresentation.java:289) ~[halbuilder-core-4.0.3.jar:na]
! at com.theoryinpractise.halbuilder.jaxrs.JaxRsHalBuilderSupport.writeTo(JaxRsHalBuilderSupport.java:36) ~[halbuilder-jaxrs-1.1.1.jar:na]

It seems like the com.theoryinpractise.halbuilder.impl.ContentType constructor should handle relative quality factors if they are part of the content type string.

Collections are not added to _embedded.

Hi,

This issue applies to v5.0.1-SNAPSHOT (and/or the current "develop" branch).

As soon as you add a second representation with .withRepresentation() or use .withRel(Rels.collection()) the representations are moved out of the _embedded elements to the outer element.

A single .withRepresentation("item", ...) is added to _embedded as expected:

{
   "_embedded": {
      "item": {
         ...
      }
   }
}

But if I use .withRel(Rels.collection("item") or add a second .withRepresentation("item", ...) the _embedded elements is empty and the representations are moved to the outer object:

{
   "_embedded": {},
   "item": [
      {
         ...
      },
      ...
   ]
}

The problem seems to be JsonRepresentationWriter.java:145 which uses

objectNode.set(rel.rel(), embedArrayNode);

instead of

embedsNode.set(rel.rel(), embedArrayNode);

A question aside from the issue:
When will v5.0.1 be available on Maven Central? Apart the from the mentioned issue v5.0.1-SNAPSHOT seems to work perfectly for me. The README.md hints that I should use com.theoryinpractise:halbuilder5:5.0.1-SNAPSHOT from Maven Central. But unfortunately I'm not allowed to use any SNAPSHOT dependencies from Maven Central. Our artifact repository won't even download them.

Regards,
Markus

README example seems to be wrong

Hi,

seems that example in README is wrong. Where it says 👍

String xml = halResource.toString(ResourceFactory.HAL_XML);
String json = halResource.toString(ResourceFactory.HAL_JSON);

it would be:
String xml = halResource.toString(RepresentationFactory.HAL_XML);
String json = halResource.toString(RepresentationFactory.HAL_JSON);

Introduction of a getBean method for the Representation Interface.

I have written a T getBean(Representation representation, Class value); Added to the Representation Interface for tag 4.0.3, locally. The reason for tag 4.0.3 because the getProperties method has the fix to recursively check if the value is a JSONArray or JSONObject. Therefore the properties map has the correct values.
The reason for the method is because when you read in hal+json for building up a bean entity based on the properties map. You will have to iterate through the property map and for the matching/marshalling to a bean entity, the casting is done manually for each bean field. Therefore having a getBean method reduces the tedious job of this. The getBean method is based upon the jackson objectMapper.readValue.

Was wondering if this would be a helpful feature?

withLink() always creates an array?

Given the following:

    RepresentationFactory rf = new StandardRepresentationFactory()
      .withFlag(RepresentationFactory.PRETTY_PRINT);
    return rf.newRepresentation("/orders")
      .withNamespace("acme", "http://docs.acme.com/relations/{rel}")
      .withLink("acme:widgets", "/widgets")
      .toString(RepresentationFactory.HAL_JSON);

I expected to get a single object for the acme:widgets link, thus:

{
  "_links" : {
    "curies" : [ {
      "href" : "http://docs.acme.com/relations/{rel}",
      "name" : "acme",
      "templated" : true
    } ],
    "self" : {
      "href" : "/orders"
    },
    "acme:widgets" : {
      "href" : "/widgets"
    }
  }
}

(Cf. the example in Section 8.2, "Link Relations", of the HAL Internet Draft, which is identical apart from more compact formatting and swapping the order of the self and curies properties.)

Instead, I get acme:widgets as a single-element array:

{
  "_links" : {
    "curies" : [ {
      "href" : "http://docs.acme.com/relations/{rel}",
      "name" : "acme",
      "templated" : true
    } ],
    "self" : {
      "href" : "/orders"
    },
    "acme:widgets" : [ {
      "href" : "/widgets"
    } ]
  }
}

How do I create a singular link?

The insertion order of embedded resources is not preserved.

Hi,

This issue applies to v5.0.1, 5.0.2-SNAPSHOT (and the current "develop" branch).

The insertion order of embedded resources is not preserved.
The example code

      ResourceRepresentation< ? > resource = ResourceRepresentation.create( new HashMap<>() );

      resource = resource
         .withLink( "foo", "/foo/1" )
         .withRepresentation( "foo", ResourceRepresentation.create( new HashMap<>() )
            .withLink( "self", "/foo/1" ) )
         .withLink( "foo", "/foo/2" )
         .withRepresentation( "foo", ResourceRepresentation.create( new HashMap<>() )
            .withLink( "self", "/foo/2" ) )
         .withLink( "foo", "/foo/3" )
         .withRepresentation( "foo", ResourceRepresentation.create( new HashMap<>() )
            .withLink( "self", "/foo/3" ) );
      
      System.out.println( JsonRepresentationWriter.create( new ObjectMapper() ).print( resource ).utf8() );

results in the following output:

{
  "_links" : {
    "foo" : [ {
      "href" : "/foo/1"
    }, {
      "href" : "/foo/2"
    }, {
      "href" : "/foo/3"
    } ]
  },
  "_embedded" : {
    "foo" : [ {
      "_links" : {
        "self" : {
          "href" : "/foo/3"
        }
      }
    }, {
      "_links" : {
        "self" : {
          "href" : "/foo/1"
        }
      }
    }, {
      "_links" : {
        "self" : {
          "href" : "/foo/2"
        }
      }
    } ]
  }
}

While the links seem to follow the insertion order the embedded resources don't. I don't know if this is actually a bug. The HAL spec is not specific here. But since links and embedded resources are JSON arrays they probably should match the insertion order.

The issue might be fixed by changing ResourceRepresentation.java:103 from

TreeMultimap.withSet().empty();

to

TreeMultimap.withSeq().empty();

and the constructor in ResourceRepresentation.java:141 accordingly.

Regards,
Markus

halbuilder-core: wrong withLink argument order in README example

example is currently:

.withLink("/todo-list/search;{searchterm}", "td:search")
.withLink("/todo-list/description", "td:description")

should be:

.withLink("td:search", "/todo-list/search;{searchterm}")
.withLink("td:description", "/todo-list/description")

add support to add title property to link items

When adding a link or creating a new representation I'm unable to add a title attribute to a link element.

I haven't found any documentation specifying how to do it either. I believe this would be a good thing to have because the hal-browser displays this information to provide additional detail about a link.

ResourceRepresentation::withLinks does not update rels correctly.

Only the rel of the last link is actually added to the previously existing rels. The reason seems to be that rels.put() actually returns a new tree on which the rel is added.

Thus the following code

    final TreeMap<String, Rel> updatedRels =
        links
            .map(Links::getRel)
            .foldLeft(
                rels,
                (accum, rel) -> !accum.containsKey(rel) ? rels.put(rel, Rels.natural(rel)) : rels);

should rather be:

    final TreeMap<String, Rel> updatedRels =
        links
            .map(Links::getRel)
            .foldLeft(
                rels,
                (accum, rel) -> !accum.containsKey(rel) ? accum.put(rel, Rels.natural(rel)) : accum);

The issue can be verified by:

    ResourceRepresentation<HashMap<Object, Object>> withLinks =
        ResourceRepresentation.create("/self", HashMap.empty())
            .withLinks(List.of(Links.create("link1", "/link1"), Links.create("link2", "/link2")));

    JsonRepresentationWriter jsonRepresentationWriter = JsonRepresentationWriter.create();
    ByteString representation = jsonRepresentationWriter.print(withLinks);

which will throw an exception.

Derive4J annotations scoped "provided" produce compiler warnings in Gradle project

When I include HalBuilder 5 in a Gradle project, I get warnings like these on compilation:

warning: unknown enum constant Flavour.Vavr
  reason: class file for org.derive4j.Flavour not found
warning: unknown enum constant ArgOption.checkedNotNull
  reason: class file for org.derive4j.ArgOption not found
warning: unknown enum constant Make.constructors
  reason: class file for org.derive4j.Make not found
warning: unknown enum constant Make.getters
warning: unknown enum constant Make.casesMatching

My workaround was to include derive4j-annotation as a compile-only dependency (loosely equivalent to Maven provided scope):

  compile 'com.theoryinpractise:halbuilder5:5.1.2'
  compileOnly 'org.derive4j:derive4j-annotation:0.12.3' // avoid HalBuilder-related compile warnings

(The down side of this is I'm hypothetically passing the problem along to anybody that depends on my code, but this particular project is an application rather than a library so that's not likely. In a library, I'd probably have to just make it an explicit compile dependency.)

I don't know what happens in straight Maven, but it seems to me provided might be the wrong scope for the Derive4J libraries, since it doesn't seem likely that it's going to be literally provided by a JDK or container.

Remove usages of com.theoryinpractise.halbuilder.DefaultRepresentationFactory#baseHref

The renaming of *Resource to *Representation solidifies the fact that HalBuilder is a representation library and not a resource library, as part of this change it makes sense that an HREF is dictated by the REST library/framework in use, and NOT HalBuilder.

Therefore we should remove any usage of the com.theoryinpractise.halbuilder.DefaultRepresentationFactory#baseHref field, including the constructor, and any relative URI resolution.

This also solves a tricky problem of trying to resolve relative URIs that are NOT URLs.

Add static factory method for JsonRepresentationReader mentioned in documentation.

Hi,

This feature request applies to v5.0.1, 5.0.2-SNAPSHOT (and the current "develop" branch).

The documentation mentions a static method

JsonRepresentationReader.create(ObjectMapper objectMapper)

However this method does not exist. Currently there is a constructor that creates a new ObjectMapper:

public JsonRepresentationReader() {
  this.mapper = new ObjectMapper();
}

A static method that can be used to inject the ObjectMapper provided by the JAX-RS ContextResolver would be quite helpful. Also making the constructor private and instead adding the static factory methods

JsonRepresentationReader.create(ObjectMapper objectMapper)

and

JsonRepresentationReader.create(Module... modules)

would make JsonRepresenationReader very much consistent with JsonRepresentationWriter.

Regards,
Markus

Running with Google Guava 15 throws java.lang.NoSuchMethodError exceptions

Google Guava version 15 replaces a lot of toImmutableList method names to the more simpler toList style - this causes...... issues.

HalBuilder should be updated to work with Guava 15.

java.lang.NoSuchMethodError: com.google.common.collect.FluentIterable.toSortedImmutableList(Ljava/util/Comparator;)Lcom/google/common/collect/ImmutableList;
  at com.theoryinpractise.halbuilder.impl.representations.BaseRepresentation.getNaturalLinks(BaseRepresentation.java:140)
  at com.theoryinpractise.halbuilder.impl.representations.BaseRepresentation.getCanonicalLinks(BaseRepresentation.java:78)
  at com.theoryinpractise.halbuilder.impl.representations.BaseRepresentation.validateNamespaces(BaseRepresentation.java:231)
  at com.theoryinpractise.halbuilder.impl.representations.BaseRepresentation.toString(BaseRepresentation.java:288)
  at com.theoryinpractise.halbuilder.impl.representations.BaseRepresentation.toString(BaseRepresentation.java:279)
  at com.theoryinpractise.halbuilder.impl.representations.BaseRepresentation.toString(BaseRepresentation.java:274)
  at smx3.resource.CustomerResource.represent(CustomerResource.java:169)

MessageBodyWriter and MessageBodyReader for HalBuilder 5.0

Hi,

This feature request applies to v5.0.1, 5.0.2-SNAPSHOT (and the current "develop" branch).

Since halbuilder5 uses a different representation object, we cannot use halbuilder-jaxrs. Instead I used a MessageBodyWriter pretty similar to the one from halbuilder-jaxrs. Since JSON reading and writing is included in halbuilder5 it might be a good idea to include the JAX-RS related stuff (MessageBodyReader and MessageBodyWriter) as well.

@Provider
@Produces( { "application/hal+json", "application/hal+xml" } )
public class JaxRsHalBuilderSupport< T > implements MessageBodyWriter< T >
{
   @Context
   private Providers providers;

   @Override
   public boolean isWriteable( Class< ? > type, Type genericType, Annotation[] annotations, MediaType mediaType )
   {
      return ResourceRepresentation.class.isAssignableFrom( type ) && HalBuilderMediaTypes.isSupported( mediaType );
   }

   @Override
   public long getSize( T t, Class< ? > type, Type genericType, Annotation[] annotations, MediaType mediaType )
   {
      return -1;
   }

   @Override
   public void writeTo( T t, Class< ? > type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap< String, Object > httpHeaders, OutputStream entityStream ) throws IOException, WebApplicationException
   {
      ResourceRepresentation< ? > representation = (ResourceRepresentation< ? >) t;

      if( mediaType.isCompatible( HalBuilderMediaTypes.HAL_JSON_TYPE ) ) {
         JsonRepresentationWriter writer = Optional
            .ofNullable(providers.getContextResolver( ObjectMapper.class, HalBuilderMediaTypes.HAL_JSON_TYPE ) )
            .map( resolver -> resolver.getContext( ObjectMapper.class ) )
            .map( JsonRepresentationWriter::create )
            .orElseGet( JsonRepresentationWriter::create );
         writer.write( representation, new OutputStreamWriter( entityStream, HalBuilderMediaTypes.DEFAULT_ENCODING ) );
      }
      else if( mediaType.isCompatible( HalBuilderMediaTypes.HAL_XML_TYPE ) ) {
         //TODO Provide a writer for HAL+XML.
         throw new RuntimeException( "No writer available for media type '" + mediaType + "'" );
      }
      else {
         throw new RuntimeException( "No writer available for media type '" + mediaType + "'" );
      }
   }
}

We don't currently need HAL+XML. Thus we throw an exception here. Also I don't have a MessageBodyReader implementation for ResourceRepresentation yet.

Regards,
Markus

Adding object through 'withBean' method doesn't ignore @JsonIgnore annotation

Hi,

In order to add selft link I'm using HALBuilder with a Jersey Filter to complete my response.

So after invoked newRepresentation(String path) method I add entity to my representation thanks to withBean method.

The class representing my entity has a field annotated @JsonIgnore. I would like to ignore this kind of field

Here is the code


Representation representation = this.newRepresentation(uriInfo.getPath());
        representation.withBean(entity);

Regards,

JVM platform encoding inferred charsets violate JSON standard

In BaseRepresentation class, the following code snippet:

public String toString(String contentType, final Set<URI> flags) {
  StringWriter sw = new StringWriter();
  toString(contentType, flags, sw);
  return sw.toString();
}

Will violate JSON standard when

  • JSON representation is used
  • JVM platform encoding is not UTF-8
  • -Dfile.encoding=UTF-8 is not given

This is due to StringWriter will use the platform encoding when writing out its contents, converting its buffer in the process.

The combination of these conditions will result in a JSON response that is not encoded in UTF-8.

Snippet to test:

import java.io.*;
public class Test {
  public static void main(String... args) {
    StringWriter w = new StringWriter();
    w.append("\u65E5\u672C\u8A9E");
    System.out.println(w.toString());
  }
}

Example:

➜  LC_ALL=en_US java Test
???
➜  LC_ALL=en_US java -Dfile.encoding=utf-8 Test
日本語
➜  LC_ALL=en_US.utf-8 java Test
日本語
➜  LC_ALL=en_US.utf-8 java -Dfile.encoding=iso-8859-1 Test
???

Empty array if no embedded representation is added

Hi,

This issue applies to v5.1.1, 5.1.2-SNAPSHOT (and the current "develop" branch).

There seems to be no way to add an empty array as an _embedded object, e.g. with

      ResourceRepresentation< ? > resource = ResourceRepresentation.empty( "/" )
         .withLink( "items", "/items" )
         .withRepresentation( "items", ResourceRepresentation.empty( "/items" )
            .withRel( Rels.collection( "item" ) ) );

      System.out.println( JsonRepresentationWriter.create( new ObjectMapper() ).print( resource ).utf8() );      

I get the following output:

{
  "_links" : {
    "self" : {
      "href" : "/"
    },
    "items" : {
      "href" : "/items"
    }
  },
  "_embedded" : {
    "items" : {
      "_links" : {
        "self" : {
          "href" : "/items"
        }
      }
    }
  }
}

Since I used .withRel( Rels.collection( "item" ) ) I expected the output to include an empty array:

{
  "_links" : {
    "self" : {
      "href" : "/"
    },
    "items" : {
      "href" : "/items"
    }
  },
  "_embedded" : {
    "items" : {
      "_links" : {
        "self" : {
          "href" : "/items"
        }
      },
      "item" : [ ]
    }
  }
}

The code

      ResourceRepresentation< ? > resource = ResourceRepresentation.empty( "/" )
         .withLink( "items", "/items/1" )
         .withRepresentation( "items", ResourceRepresentation.empty( "/items/1" )
            .withRel( Rels.collection( "item" ) )
            .withRepresentation( "item", ResourceRepresentation.empty() ) );

results in "item": [ { } ] which is not correct.

The code

      ResourceRepresentation< ? > resource = ResourceRepresentation.empty( "/" )
         .withLink( "items", "/items/1" )
         .withRepresentation( "items", ResourceRepresentation.empty( "/items/1" )
            .withRel( Rels.collection( "item" ) )
            .withRepresentation( "item", ResourceRepresentation.create( Collections.EMPTY_LIST ) ) );

results in an Exception:

Exception in thread "main" java.lang.IllegalStateException: Unable to serialise a non Object Node
	at com.theoryinpractise.halbuilder5.json.JsonRepresentationWriter.renderJsonProperties(JsonRepresentationWriter.java:151)
...

The code

      ResourceRepresentation< ? > resource = ResourceRepresentation.empty( "/" )
         .withLink( "items", "/items" )
         .withRepresentation( "items",
            ResourceRepresentation.create( "/items", ImmutableMap.of( "item", Collections.EMPTY_LIST ) ) );            

actually provides the expected result although it seems to be more of a work around to set the value of the ResourceRepresentation to an object { "list": [ ] }. The bad thing of this work around is that we will need a check for an empty list beforehand and if it's empty, we create this representation, else we create the "normal" representation. It might be a good idea to make the initial example with .withRel( Rels.collection( "item" ) ) lead to the same result.

Regards,
Markus

Representations with empty value produce an NPE.

Hi,

This issue applies to v5.0.1, 5.0.2-SNAPSHOT (and the current "develop" branch).

Representations with empty value produce an NPE:

      ResourceRepresentation< ? > resource = ResourceRepresentation.empty()
       .withLink( "foo", "/foo" )
       .withRepresentation( "foo", ResourceRepresentation.create( new HashMap<>() )
          .withLink( "self", "/foo" ) );

results in

Exception in thread "main" java.lang.NullPointerException
	at com.theoryinpractise.halbuilder5.json.JsonRepresentationWriter.renderJsonProperties(JsonRepresentationWriter.java:159)
	at com.theoryinpractise.halbuilder5.json.JsonRepresentationWriter.renderJson(JsonRepresentationWriter.java:104)
	at com.theoryinpractise.halbuilder5.json.JsonRepresentationWriter.write(JsonRepresentationWriter.java:66)
	at com.theoryinpractise.halbuilder5.json.JsonRepresentationWriter.print(JsonRepresentationWriter.java:60)

since the corresponding JsonNode is NULL in renderJsonProperties(). A NULL check before JsonRepresentationWriter.java:159 seems to fix the problem. It's not a big issue though since you can easily work around by using

ResourceRepresentation.create( new HashMap<>() )

instead of

ResourceRepresentation.empty()

but since empty() exists it should not throw an NPE.

Regards,
Markus

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.