3 Replies Latest reply on Apr 27, 2017 1:47 AM by Horia Chiorean

    Custom Node Modeling question

    David Harrison Newbie

      Hello,

       

      I have a scenario where I need to create a custom Node Definition for a Brand / Customer,  it will have some basic properties, but it most of it's content will be on its child nodes. It will have a Style content node as a child, and up to three logos (main, header, footer).

       

      For the Brand's Logos (files), is this the right way to model the CND? I'm trying to setup an explicit reference to the binaries/logos as properties so the ModeShape garbage collection process does not remove them. FYI, I'm using the database for binary storage and regular content.

       

      Thanks! I'm open to any suggestions or feedback.

       

      Brand CND

      <jcr='http://www.jcp.org/jcr/1.0'> \

      <nt='http://www.jcp.org/jcr/nt/1.0'> \

      <mix='http://www.jcp.org/jcr/mix/1.0'> \

      <brand='http://www.modeshape.org/examples/brand/1.02'>

      <style='http://www.modeshape.org/examples/style/1.01'>

      [brand:Brand] >  mix:created, mix:lastModified

        - brand:code (string)

        - brand:name (string)

        + brand:style (style:Style) = style:Style

        + brand:logo_main (nt:file) = nt:file

        + brand:logo_header (nt:file) = nt:file

        + brand:logo_footer (nt:file) = nt:file

       

      Style CND

      <jcr='http://www.jcp.org/jcr/1.0'>

      <nt='http://www.jcp.org/jcr/nt/1.0'>

      <mix='http://www.jcp.org/jcr/mix/1.0'>

      <style='http://www.modeshape.org/examples/style/1.01'>

      [style:Style] > mix:created, mix:lastModified, mix:versionable

        - style:system_code (string)

        - style:subsystem_code (string)

        - style:client_code (string)

        - style:brand_primary_color

        - style:brand_secondary_color

        - style:button_primary_color

       

      Sample Insertion / Node Creation Script

       

      curl -m 60 -H "Content-Type: application/json" \
        -H "Accept: application/json" \
        --user admin:admin  \
        -X POST http://localhost:8080/modeshape-psi/rest/repo/default/items/brandTest001 \
      -d @- << EOF 
       { 
        "jcr:primaryType" : "brand:Brand", 
        "brand:code" : "brandTest001" 
       }
      EOF
      
      
      curl -m 60 -H "Content-Type: application/json" \
        -H "Accept: application/json" \
        --user admin:admin  \
        -X POST http://localhost:8080/modeshape-psi/rest/repo/default/items/brandTest001/brand%3astyle \
      -d @- << EOF 
        {
         "jcr:primaryType":"style:Style",
         "style:system_code" : "lc",
         "style:subsystem_code" : "ucs",
         "style:client_code": "psi",
         "style:brand_primary_color" : "#701c45",
         "style:brand_secondary_color" : "#003056",
         "style:button_primary_color" : "#003056"
        }
      EOF
      
      curl -X POST --data-binary @sample-content/system/lc/ucs/branding/psi/logo/logo.png --user admin:admin http://localhost:8080/modeshape-psi/rest/repo/default/upload/brandTest001/brand%3alogo_main
      curl -X POST --data-binary @sample-content/system/lc/ucs/branding/psi/logo/logo2.jpg --user admin:admin http://localhost:8080/modeshape-psi/rest/repo/default/upload/brandTest001/brand%3alogo_header
      curl -X POST --data-binary @sample-content/system/lc/ucs/branding/psi/logo/logo3.jpg --user admin:admin http://localhost:8080/modeshape-psi/rest/repo/default/upload/brandTest001/brand%3alogo_footer
      
      
      
        • 1. Re: Custom Node Modeling question
          Horia Chiorean Master

          The binary garbage collector should never touch binaries that are referenced by active nodes. So as long as a binary property is correctly set on a node and that node is not removed, the binary value should not be garbage collected.

           

          When you're using the REST service to upload binaries, the path of the URL should point to a binary property (note that the CND type is "binary"). So for example:

           

          [nt:resource] > mix:mimeType, mix:lastModified primaryitem jcr:data

            - jcr:data (binary) mandatory

           

          represents the [nt:resource] type with a jcr:data binary property (note the name of the type).

           

          If you want the logo_* items to be binaries, they should be binary properties, not nt:file children. The REST methods that allow updating/changing binaries only work with binary properties, not children which in turn have binary properties.

          1 of 1 people found this helpful
          • 2. Re: Custom Node Modeling question
            David Harrison Newbie

            Thanks for the response and helping me understand ! If I change the logo properties to be (binary), is there a way It can still capture the mime type (on upload)? Currently, the logo files could be jpg, png, or other formats.

            The system retrieving the brand info needs to retrieve images / binaries  and also pass along the mime type, so we Add the right type of file extension on it and include as a web resource for a customer branded web portal .

             

            Based on your comment about the REST api only allowing updates of binary types, not nt:file,  and needing to know the mime type (or file extension) of a logo,  I'm currently considering the following CND definition.

            For each logo (header for example), there is a property with ".jpg"   and ".png" on the end of the property name.   Only one of those would be used, per logo type.

             

            Then, on retrieval a Brand content node,  I can parse for elements containing  (for example)  logo_main,  and then determine the file type by the full name of the property such as below.  For each pair, I'll only have a jpg or png present.

            • psibranding:logo_main.png
            • psibranding:logo_main.jpg

             

            Does that make sense?  Is there a better way?

             

            Revised Brand CND

             

            <jcr='http://www.jcp.org/jcr/1.0'>
            <nt='http://www.jcp.org/jcr/nt/1.0'>
            <mix='http://www.jcp.org/jcr/mix/1.0'>
            <psibranding='http://www.modeshape.org/examples/psibranding/1.1'>
            <psistyle='http://www.modeshape.org/examples/psistyle/1.01'>
            [psibranding:Branding] > mix:created, mix:lastModified, mix:versionable
              - psibranding:system_code (string)
              - psibranding:subsystem_code (string)
              - psibranding:client_code (string)
              + psibranding:style (psistyle:Style) = psistyle:Style
              - psibranding:logo_main.jpg (binary)
              - psibranding:logo_header.jpg (binary)
              - psibranding:logo_footer.jpg (binary)
              - psibranding:logo_main.png (binary)
              - psibranding:logo_header.png (binary)
              - psibranding:logo_footer.png (binary)
            

             

             

            Sample view below

            2017-04-26 11_14_59-192.168.99.100_8080_modeshape-psi_rest_repo_default_items_system_lc_ucs_branding.png

            • 3. Re: Custom Node Modeling question
              Horia Chiorean Master

              First, from a modelling perspective, your original CND (which used nt:file) is the correct one IMO and the one which I would recommend when using JCR.

               

              The problem here is that you're trying to work with your model via ModeShape's REST service and not the full JCR API. The REST service was added a simple nice-to-have with minimal functionality and never meant to be an alternative to the JCR API (as such it only offers minimal methods to CRUD nodes and in this case binary properties).

              For a production system using ModeShape that requires some REST interface(s), I would recommend developing your own REST endpoints (with logic specific to your domain) and make those endpoints use the ModeShape/JCR API behind the scenes (i.e. on the server using the "real" JCR API). This would allow you to model your domain correctly and give you access to the full JCR feature set.

               

              Regarding mime type detection: unless you're using nt:file (like the first solution) the built-in mime-type detection will not work. So changing the model to v2 (using properties) will not give you mime type detection. Your second CND would work if you want to only use the ModeShape REST API and upload binaries that way, but for a production system I would recommend the approach described in my previous paragraph.