Refresh remote folder

  • (2 Pages)
  • +
  • 1
  • 2

28 Replies - 571 Views - Last Post: 13 February 2012 - 12:19 PM Rate Topic: -----

Topic Sponsor:

#16 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: Refresh remote folder

Posted 10 February 2012 - 05:20 AM

Nothing i can find there sorry
Was This Post Helpful? 0
  • +
  • -

#17 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 719
  • View blog
  • Posts: 1,692
  • Joined: 05-May 05

Re: Refresh remote folder

Posted 10 February 2012 - 02:35 PM

I tried using the WatchService API to no avail. I don't think SAMBA is a supported file system.

I made a JCIFS wrapper for receiving SAMBA directory notifications. You can get the source here. There's also a class, SmbNotifier, that will run the application. To compile and run you need to JCIFS binaries, which can be found here.

java -cp ".:jcifs-1.3.17.jar" SmbNotifier "smb://<host>/<dir>/" "<domain>" "<user>" "<pass>"



When you add a file in the directory the console will output a message.

SAMBA share:

Posted Image

Linux:

Posted Image

There's a NotificationHandler that defines two callbacks, handleNewFile(String file) and handleDeletedFile(String file), where you can create a new SmbFile and open a byte stream to the PDF.

@Override
void handleNewFile(String file) {
    System.out.println(file + " added.");
    if(file.endsWith(".pdf")) {
        try {
            String userInfo = auth.getDomain() + ";"
                    + auth.getUser() + ":" + auth.getPass();
            //You must re-authenticate here
            SmbFile f = new SmbFile(url + "" + file, new NtlmPasswordAuthentication(userInfo));
            PdfReader rdr = new PdfReader(f.getInputStream());
            System.out.println("pdf size (bytes) = "+rdr.getFileLength());
            rdr.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}



The underlying implementation uses a thread to poll the directory, where the time between polls can be specified.

Note that if your ESD software overwrites the same PDF, a notification will not be generated. It only works for new and deleted files as of right now. If this is the case, let me know, and I'll add a new callback.
Was This Post Helpful? 0
  • +
  • -

#18 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: Refresh remote folder

Posted 10 February 2012 - 04:31 PM

Quote

I tried using the WatchService API to no avail.


I'm guessing for the same reasons as i mentioned above. Did you get an instance of PollingWatchService?
Was This Post Helpful? 0
  • +
  • -

#19 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 719
  • View blog
  • Posts: 1,692
  • Joined: 05-May 05

Re: Refresh remote folder

Posted 10 February 2012 - 05:10 PM

Wasn't aware it existed. I don't think that API is in the Sun distro. It's in OpenJDK. Honestly, the WatchService API is a pain in the ass. JCIFS's API is very simple and does what I need.

I don't think the Java I/O APIs support SAMBA. When I try new File("smb://host/dir").exists() it returns false. Then I tried using the Path class to no avail. There's an open bug filed for WatchService and SAMBA. The google results for "WatchService SAMBA" aren't very promising either, so I'm just going to assume it's not a workable solution.

This post has been edited by blackcompe: 10 February 2012 - 05:11 PM

Was This Post Helpful? 0
  • +
  • -

#20 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: Refresh remote folder

Posted 10 February 2012 - 05:29 PM

Quote

I don't think that API is in the Sun distro. It's in OpenJDK.


I'll see if i can get hold of the Sun source - the package >6 is not available on my current system.
I saw PollingWatchService in the OpenJDK as you said, but as yet have seen no means of forcing the instantiation of one (the ctor is package-private).

I'll take a look at your code at some point. At the moment, i'm not really clear why Samba is really necessary in the Java code when the protocol is being handled by Linux. Why not just poll the mountpoint and ignore the Samba element - or am i missing something?
Was This Post Helpful? 1
  • +
  • -

#21 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 719
  • View blog
  • Posts: 1,692
  • Joined: 05-May 05

Re: Refresh remote folder

Posted 11 February 2012 - 02:18 AM

Quote

Why not just poll the mountpoint and ignore the Samba element - or am i missing something?


I found a workaround. You have to go through GVFS. Wow, five hours of work for nothing...

import java.io.*;
import java.util.*;
    

public class SambaTest {
    public static void main(String[] args) throws Exception {
        String server = "";
        String share = "";
        String file = "";
        String path = System.getProperty("user.home") + "/.gvfs/" + share.toLowerCase() + " on " + server + "/" + file;
        File f = new File(path);
        Scanner s = new Scanner(f);
        while(s.hasNextLine())
            System.out.println(s.nextLine());
    }
}



Now you can use the WatchService. Goose, +1 for making me look one last time and helping me to understand Linux and SAMBA a bit better.

This post has been edited by blackcompe: 11 February 2012 - 02:26 AM

Was This Post Helpful? 0
  • +
  • -

#22 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: Refresh remote folder

Posted 11 February 2012 - 03:55 AM

Well done for that! To answer my own question below:

Quote

Why not just poll the mountpoint and ignore the Samba element - or am i missing something?


i actually tried this. The WatchService worked ok when the share was written to from Linux but not from Windows

Quote

Wow, five hours of work for nothing...


I don't think so. Your workaround involves GVFS. Not everyone has that - i normally don't for one and would normally mount -t cifs at the command line. Somehow i think there's more to come on this one...

This post has been edited by g00se: 11 February 2012 - 03:56 AM

Was This Post Helpful? 0
  • +
  • -

#23 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 719
  • View blog
  • Posts: 1,692
  • Joined: 05-May 05

Re: Refresh remote folder

Posted 11 February 2012 - 04:51 AM

Quote

Quote

Wow, five hours of work for nothing...


I don't think so. Your workaround involves GVFS. Not everyone has that - i normally don't for one and would normally mount -t cifs at the command line. Somehow i think there's more to come on this one...


I meant five hours writing the wrapper.

I tried using this WatchService snippet with the GVFS path, but it didn't detect anything, not even changes from Linux.

This works perfectly on my machine.

import java.io.*;
import java.util.*;
    

public class SambaTest {
    public static void main(String[] args) throws Exception {
        String server = "";
        String share = "";
        String path = System.getProperty("user.home") + "/.gvfs/" + share.toLowerCase() + " on " + server;
        File f = new File(path);
        long lastModified = f.lastModified();
        long tmp;
        while(true) {
            tmp = f.lastModified();
            if(tmp != lastModified) {
                System.out.println("Share modified.");
                lastModified = tmp;
            }
        }
    }
}



Quote

Not everyone has that - i normally don't for one and would normally mount -t cifs at the command line.


If that were the case, my JCIFS wrapper would probably work. JCIFS is a pure Java solution that communicates over the smb protocol. The main component is a subclass of URLConnection. All OS-level stuff is bypassed.

This post has been edited by blackcompe: 11 February 2012 - 04:53 AM

Was This Post Helpful? 0
  • +
  • -

#24 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: Refresh remote folder

Posted 11 February 2012 - 05:14 AM

Quote

I meant five hours writing the wrapper.


Yes, i know ;) What i'm getting at is that your code could be very useful. My guess is that support for these watch services is basic at the moment and your code could be integrated, possibly via the SPI mechanism.

I don't yet know how all this new file system stuff is integrated but http://docs.oracle.c...emProvider.html looks like an interesting point of departure. From
an implementational POV i'm guessing what you'd do is return a WatchService based on the type of file system being supported. When i ran (on Windows and Linux) http://docs.oracle.c...lledProviders() all i got was native fs + zip fs. Now if it were able to return CifsFileSystem too ...
Was This Post Helpful? 1
  • +
  • -

#25 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 719
  • View blog
  • Posts: 1,692
  • Joined: 05-May 05

Re: Refresh remote folder

Posted 11 February 2012 - 06:25 AM

Quote

My guess is that support for these watch services is basic at the moment and your code could be integrated, possibly via the SPI mechanism.


Sweet! I'm going to look into this. I'll let you know what I come up with. I see an open source project in the making!
Was This Post Helpful? 0
  • +
  • -

#26 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: Refresh remote folder

Posted 13 February 2012 - 08:07 AM

Even more reason your code could be useful: i tried your .gvfs suggestion. This was the scenario:

1. Linux box A, running Samba server with share S
2. Linux box B with share S mounted
3, WatchService running on B listening to ~/.gvfs/S (In reality Gigolo produces something other than 'S' - a nasty space-ridden path)
4. Wrote into share on A with touch S/foo

Nothing at all was picked up by the WatchService
Was This Post Helpful? 0
  • +
  • -

#27 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 719
  • View blog
  • Posts: 1,692
  • Joined: 05-May 05

Re: Refresh remote folder

Posted 13 February 2012 - 11:42 AM

Quote

Even more reason your code could be useful


Sweet! I just finished up a partial implementation of the Service Provider Interface. I've got this working:

private final Map<String, ?> createRealEnv() {
    final Map<String, String> env = new HashMap<>();
    env.put("domain", domain);
    env.put("user", user);
    env.put("pass", pass);
    return env;
}

@Before
public void setUp() throws Exception {
    String url = "smb://<host>/<share>/";
    URI uri = new URI(url);
    FileSystemsProvider provider = FileSystems.newFileSystem(uri, createRealEnv()).provider();
    InputStream is = null;
    BufferedReader buf = null;
    try {
        is = provider.newInputStream(system.getPath("smb://<host>/<share>/<file>"));
        buf = new BufferedReader(new InputStreamReader(is));
    }catch(Exception e){}
}



I hope to be near finished in a few days.

This post has been edited by blackcompe: 13 February 2012 - 11:45 AM

Was This Post Helpful? 0
  • +
  • -

#28 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: Refresh remote folder

Posted 13 February 2012 - 12:11 PM

Quote

the Service Provider Interface


Interesting. There seems to be a shortage of docs on this. Have you got a javadoc link for this?
Was This Post Helpful? 0
  • +
  • -

#29 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 719
  • View blog
  • Posts: 1,692
  • Joined: 05-May 05

Re: Refresh remote folder

Posted 13 February 2012 - 12:19 PM

I meant to say the system provider implementation.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2