Class BrowserFileTransfer

java.lang.Object
vaadinx.BrowserFileTransfer

public final class BrowserFileTransfer extends Object
INTERNAL — do not use. Not part of the emulated Swing/AWT API surface and has no stability guarantee.

Shared browser file-transfer mechanics behind the two file-pick hosts — FileDialog and JFileChooser. Both bridge the java.io.File semantic gap the same way: a LOAD stages a browser Upload into a per-session temp file; a SAVE hands back a temp target path and offers a synthetic, non-modal download affordance once the app has written it. The hosts differ in how they park (FileDialog is-a modal Dialog; JFileChooser composes an internal modal JDialog JOptionPane-style) and in their result shape, so park + buttons + result promotion stay host-side; only the transfer mechanics live here. Which files a SAVE actually produced — the walk of the transfer directory and the order its results are shown in — is SaveOutputs, kept apart because it is pure and has no Vaadin in it.

  • Method Summary

    Modifier and Type
    Method
    Description
    static File
    Allocate a fresh per-session temp target for a SAVE under name; the app writes to it after the host's modal name-pick returns.
    static void
    openDownloadDialog(byte[] content, String name)
    In-memory variant of openDownloadDialog(File, String) for content that is fully produced before the dialog opens (e.g. the virtual PDF printer in :emulators-printing).
    static void
    The synthetic, non-modal download affordance — a side-channel the emulated Swing app has no handle to (like an accessibility overlay).
    static String
    safeName(String fileName)
    Browsers send a bare filename, but defend against path traversal in a crafted multipart filename before using it to open a server-side file.
    static String
    sizeText(File target)
    Honest "current bytes on disk" cue for the download dialog.
    static List<File>
    wireUpload(com.vaadin.flow.component.dialog.Dialog peerDialog, boolean multi, BiPredicate<File,String> accept, List<String> acceptedExtensions, com.vaadin.flow.component.button.Button approveButton)
    Build the LOAD content — a browser Upload plus a server-side filter-rejection notice — into peerDialog, and return the live list each accepted upload stages into.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • wireUpload

      public static List<File> wireUpload(com.vaadin.flow.component.dialog.Dialog peerDialog, boolean multi, BiPredicate<File,String> accept, List<String> acceptedExtensions, com.vaadin.flow.component.button.Button approveButton)
      Build the LOAD content — a browser Upload plus a server-side filter-rejection notice — into peerDialog, and return the live list each accepted upload stages into. The caller adds its own approve/cancel buttons (labels and dispose target differ per host) and reads the returned list once the modal park unwinds.

      Each part is written to a per-session temp file, then the real accept predicate runs against the real staged file: matches are added to the list and approveButton is enabled; non-matches are deleted with a notice. We can't avoid the transfer (the browser uploads on selection) but we refuse to hand the app a file the filter rejects, matching the desktop "can't pick it" contract. acceptedExtensions, when non-null, pre-narrows the browser picker (best-effort UX only — the authoritative gate is always the server-side accept).

      Parameters:
      peerDialog - the Vaadin dialog hosting the pick; Upload + notice are appended to it.
      multi - whether multiple files may be staged.
      accept - (dir, name) -> keep?; null accepts all.
      acceptedExtensions - extensions (no leading dot) for the browser accept-attribute hint; null skips the hint.
      approveButton - enabled once the first file stages.
      Returns:
      the synchronized, growing list of staged temp files (read side runs on a different request thread than the upload callback).
    • newSaveTarget

      public static File newSaveTarget(String name)
      Allocate a fresh per-session temp target for a SAVE under name; the app writes to it after the host's modal name-pick returns. We don't create the file — the app's stream does — we only own the directory.
      Returns:
      the temp File the app should write to.
    • openDownloadDialog

      public static void openDownloadDialog(File target, String name)
      The synthetic, non-modal download affordance — a side-channel the emulated Swing app has no handle to (like an accessibility overlay). Opened once the SAVE name-pick returns, before the app has written anything.

      Bound to the directory, not to target (D_save_binds_download). Swing never promised the app writes to exactly the path it was handed: deriving is routine (path + ".xls", an extension swap, several files from one pick, a library appending its own suffix), and every derivation lands a sibling. Binding to the predicted path therefore offered a file that was often never written while the real output sat beside it, unreachable. So the watcher walks target's parent — the fresh, empty, per-show directory from SessionTempFiles.newTransferDir() — and offers a link per file it finds, under the name the app actually produced rather than the name the user typed.

      The server still can't know when the app has finished writing (the write may be async / background), so the human stays the completion oracle: the size readouts auto-refresh on the shared per-UiScheduler cadence and push live (Push is mandatory, so no manual-refresh fallback is needed), and an early click that grabs a partial file is recoverable by waiting and clicking again. Rows are keyed by relative path and reconciled rather than rebuilt, so a library that writes report.xls.tmp and renames it renders the way watching the folder in a file manager does.

      Parameters:
      target - the path handed to the app; only its parent directory is watched, and only its name seeds the match-first ordering.
      name - the name the user typed, for the dialog title and ordering.
    • openDownloadDialog

      public static void openDownloadDialog(byte[] content, String name)
      In-memory variant of openDownloadDialog(File, String) for content that is fully produced before the dialog opens (e.g. the virtual PDF printer in :emulators-printing). The completeness dance of the file variant — size watcher, partial-download caveat — doesn't apply: the bytes are final, so the dialog is just a download link.
    • sizeText

      public static String sizeText(File target)
      Honest "current bytes on disk" cue for the download dialog.
    • safeName

      public static String safeName(String fileName)
      Browsers send a bare filename, but defend against path traversal in a crafted multipart filename before using it to open a server-side file.