Hi Marcel,

trying your jsp (unchanged, but reading some more characters), I get the following result:

<br/>Event occurred. Path=/test.pdf/jcr:content
<br/><?xml version="1.0" encoding="utf-8"?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getlastmodified/>
<D:getcontentlength/>
<D:resourcetype/>
</D:prop>
</D:propfind>
<br/>

I really don't know how to interpret this. Oddly enough, I'm now unable to reproduce the original behavior (empty jcr:data) myself -- it's the same DAV message I'm getting from my own code now...

Regards,
Kim



On 09.02.2007, at 15:47, Marcel Reutegger wrote:

Hi Kim,

you wrote that the session is shared among several listeners. while it may be ok in some cases to use multiple threads that read from a single session (this is not 100% supported), you have to make sure that only one thread *writes* to a session instance and no other thread reads from that session instance. Just to make sure you are not doing work with multiple threads on the same session instance...

I used the following jsp as a test case and the listener works fine. The jsp registers a listener for 60 seconds and prints out the first 32 characters of any file that is created within that time:

<%@ page import="org.apache.jackrabbit.j2ee.RepositoryAccessServlet,
                 javax.jcr.Repository,
                 javax.jcr.Session,
                 javax.jcr.SimpleCredentials,
                 javax.jcr.observation.EventListener,
                 javax.jcr.observation.EventIterator,
                 javax.jcr.observation.Event,
                 javax.jcr.Node,
                 java.io.InputStream,
                 javax.jcr.RepositoryException,
                 java.io.IOException,
                 java.io.PrintWriter"%><html>
<head>
<title>Jackrabbit JCR-Server</title>
</head>
<body>
Listening for nt:file events:
<%
Repository rep = RepositoryAccessServlet.getRepository (pageContext.getServletContext()); final Session s = rep.login(new SimpleCredentials("jack", "rabbit".toCharArray()), null);
    final JspWriter finalOut = out;
    try {
        s.getWorkspace().getObservationManager().addEventListener(
                new EventListener() {
                    public void onEvent(EventIterator events) {
                        while (events.hasNext()) {
                            Event e = events.nextEvent();
                            try {
Node n = (Node) s.getItem(e.getPath ());
                                if (n.hasProperty("jcr:data")) {
finalOut.println("<br/>Event occurred. Path=" + e.getPath()); InputStream in = n.getProperty ("jcr:data").getStream();
                                    byte[] data = new byte[32];
                                    int r = in.read(data, 0, 32);
finalOut.println("<br/>" + new String(data, 0, r) + "<br/>");
                                    finalOut.flush();
                                }
                            } catch (Exception ex) {
ex.printStackTrace(new PrintWriter (finalOut));
                            }
                        }
                    }
                }, Event.NODE_ADDED, "/", true, null, null, true);

        for (int i = 0; i < 60; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // ignore
            }
            out.println(".");
            out.flush();
        }
    } finally {
        s.logout();
    }
%>
</body>
</html>

regards
 marcel

Kim Altintop wrote:
Hi Marcel,
thanks for answering so quickly.
I've put together a simple class that illustrates the issue. The whole point of accessing the jcr:data property directly (instead of using e.g. Workspace.copy) it that the file is not reflected as nt:file in the target workspace, but
rather as a binary property of a domain-specific node type.
Thanks for looking into this,
Kim
// I'm using this as a singleton Bean instantiated by Spring (which also
// injects the session which is shared among all my listeners) with
// jackrabbit 1.2.1 under Tomcat 5.5.20 deployed in 'model 1'.
public class SimpleWebdavDropFileListener implements EventListener {
private final static Logger log = LoggerFactory.getLogger (MyListener.class);
  private Session systemSession;
  public SimpleWebdavDropFileListener(Session session) {
    this.systemSession = session;
ObservationManager omgr = systemSession.getWorkspace ().getObservationManager();
    omgr.addEventListener(
      this, // register myself
            Event.NODE_ADDED, // on node added events
            session.getRootNode().getPath(), // at root node
            true, // and descendants
            null, // not using uuid constraints
new String[] { "nt:file" }, // receiving events only for files
            false // ignoring local events
    );
  }
  public void onEvent(EventIterator events) {
    while (events.hasNext()) {
      Event event = events.nextEvent();
      // strip leading '/'
      String path = event.getPath().substring(1);
      try {
        Node theFile = systemSession.getRootNode().getNode(path);
        Node contentNode = theFile.getNode("jcr:content");
// this will be zero unless we're implementing SynchronousEventListener long dataLength = contentNode.getProperty ("jcr:data").getLength(); log.info("Just received a file and the size of it's jcr:content/jcr:data property is: " + dataLength); // walk through all properties and output their name and value (as string) // -> every property except jcr:data will have a value printed
        PropertyIterator props = contentNode.getProperties();
        while (props.hasNext()) {
          Property prop = props.nextProperty();
log.info(prop.getName() + " has value: " + prop.getString ());
        }
      } catch (Exception e) {
        e.printStackTrace(); // whatever
      }
    }
  }
}
Marcel Reutegger <marcel.reutegger <at> gmx.net> writes:
 >
 > Hi Kim,
 >
> I'm not able to reproduce the behaviour you described. Though I didn't use > WebDAV to import files, but just imported them using a JCR session.
 >
> Can you please provide a code fragment that shows how you access the content
 > from within the event listener?
 >
 > regards
 >   marcel
 >
 > Kim Altintop wrote:
 > > Hi,
 > >
> > I'm trying to implement a simple "Drop Folder" setup where users would > > connect to one Jackrabbit workspace using (simple) WebDAV, drop files in > > there, and an EventListener listening for NODE_ADDED events (restricted > > to "nt:file") would then copy the file(s) to another workspace. As it > > turned out, the EventListener is able to locate the just- dropped file > > and read its properties but the jcr:data property is always empty (i.e.
 > > contains no data). If I change my listener to implement
> > SynchronousEventListener it works fine. However, from the spec I would
 > > expect it to work just the other way round...
 > >
 > > Am I getting something wrong here?
 > >
 > > Regards,
 > > Kim
 > >
 > >
 >
 >

Reply via email to