10 Replies Latest reply on Oct 7, 2013 11:05 AM by nl

    How to sequence a subgraph?

    nl

      Hi,

       

      Using the session.importXML() creates a couple of nodes but is not running configured sequencers. Is there a way to tell MS to sequence content within a subgraph?

      Background: I use session.exportSystemView("/files") on an old repository (MS 2.8) to solely export our documents and run the import on a new (MS 3.5) repository. The import works fine but I need the "files" to be re-sequenced. In the old rep the sequenced nodes are located under "/sequenced/...".

       

      Is there a way (hack) do so?

       

      Thanks, Niels

        • 1. Re: How to sequence a subgraph?
          hchiorean

          After session.importXML() finishes, are all the expected nodes in the "correct" place from the configured sequencers' perspective ? In other words, do the node paths match the input path of the configured sequencers ?

          If yes, then after calling session.save() (you need to do that because importXML() is a session-scoped method) the nodes should be (re)sequenced (assuming the sequencers are configured correctly).

           

          You can also turn TRACE logging on for org.modeshape.jcr and check for additional information which may indicate why the sequencers aren't firing.

          1 of 1 people found this helpful
          • 2. Re: Re: How to sequence a subgraph?
            nl

            This is really weird.

            Upon creating a new repository it is populated with some content, e.g "/files" is created.

            The XML to import also contains the "/files" node. Now by importing the xml file a same-name-sibling "/files[2]" is created and all the content being imported is stored there. This is not exactly what I want. Therefore I removed the files node prior to import:

             

            {code}

            Node rn = session.getNode("/files");

            session.removeItem(rn.getPath());

            session.importXML(...);

            session.save();

            {code}

             

            In the logs I read that the sequencer is not matching because the rules do not allow /files[2]/... (but only /file/...). Now if I query the documents after import (after session.save()) the path-name is "files/..." not "/files[2]".

            Therefore I changed the code above to:

             

            {code}

            Node rn = session.getNode("/files");

            session.removeItem(rn.getPath());

            session.save();

            session.importXML(...);

            session.save();

            {code}

             

            This time the sequencers are triggered, but the result look like this:

            /sequenced/pdf/1.pdf

            /sequenced[2]/pdf/2.pdf

            /sequenced[3]/pdf/3.pdf

            ...

             

            Whereas creating nodes "the normal way" the sequencer does not create same-name-siblings...

            • 3. Re: Re: How to sequence a subgraph?
              hchiorean

              What does your sequencer configuration look like ?

              • 4. Re: Re: Re: How to sequence a subgraph?
                nl

                {code}

                "pdfs":{

                                "name" : "PDF sequencer",

                                "classname" : "org.modeshape.sequencer.pdf.PdfMetadataSequencer",

                                "pathExpressions" : [ ":/files(//)(*.pdf[*])/jcr:content[@jcr:data] => :/sequenced/pdf/$1" ]

                            }

                {code}

                • 5. Re: Re: Re: How to sequence a subgraph?
                  hchiorean

                  Is this a custom sequencer ?  - it's not part of the default ModeShape 3.x sequencers.

                  If this is the case, you really need to check the code from this sequencer, because it's responsible for generating the output nodes.

                  • 6. Re: Re: Re: Re: How to sequence a subgraph?
                    nl

                    Hmm, I created the following test case with a build-in sequencer:

                     

                    sequencer config:

                     

                    {code}

                    "images" : {

                                    "name" : "Images",

                                    "classname" : "image",

                                    "pathExpressions":[ ":/files(//)(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data] => :/sequenced/images/$1" ]

                                }

                    {code}

                     

                    Test Case:

                     

                    {code}

                            Session session = ...;

                            Node n = session.getNode("/files");

                            Node fn = n.addNode("test1.jpg", JcrConstants.NT_FILE);

                            Node resNode = fn.addNode(JCR_CONTENT, NT_RESOURCE);

                            ByteArrayInputStream bin = new ByteArrayInputStream(TestData.imageValue.getBytes());

                            javax.jcr.Binary b = session.getValueFactory().createBinary(bin);

                            resNode.setProperty(JcrConstants.JCR_DATA, b);       

                     

                    //      Case b): Call save() and wait for sequencer to be run       

                    //      session.save();       

                    //      <wait for sequencer>

                                           

                            fn = n.addNode("test2.jpg", JcrConstants.NT_FILE);

                            resNode = fn.addNode(JCR_CONTENT, NT_RESOURCE);

                            bin = new ByteArrayInputStream(TestData.image2Value.getBytes());

                            b = session.getValueFactory().createBinary(bin);

                            resNode.setProperty(JcrConstants.JCR_DATA, b);                               

                            session.save();

                            <wait for sequencer>       

                    {code}

                     

                    If I store 2 images within one session transaction, the sequencer output will be like

                    /sequenced/images/test2.jpg

                    /sequenced[2]/images/test1.jpg

                     

                    If I call session.save() after first upload, wait for the sequencer and then store the next image the sequencer output will be like

                    /sequenced/images/test1.jpg

                    /sequenced/images/test2.jpg

                    • 7. Re: Re: Re: Re: How to sequence a subgraph?
                      hchiorean

                      Ok, this makes more sense now: what's happening is that each time a sequencer is run, it searches for the root (parent) output path and if it cannot find it, it will create it. Therefore if your node-types allow SNS and you don't save the output of a sequencing run, each subsequent run doesn't see the output path and will attempt to create a new one (each sequencing operation is run in isolation from the others, using its own internal session)

                       

                      I think the easiest solution is to create & save the root output path first (in this case "sequenced/images") and then start the sequencing runs.

                      • 8. Re: Re: Re: Re: How to sequence a subgraph?
                        nl

                        Yes, that definitely works.

                        Thanks a lot.

                         

                        Regarding the subject of this thread and just because I am curious. Is there a way to manually trigger a sequencer (an automated one) to run?

                        • 9. Re: Re: Re: Re: How to sequence a subgraph?
                          rhauch

                          It's coming in 3.6: see our blog post and our documentation.

                          • 10. Re: Re: Re: Re: How to sequence a subgraph?
                            nl

                            ModeShape rocks!!!