# JNLP API Examples

This chapter includes the following topics:

- Introduction
- Using a `BasicService` Service
- Using a `ClipboardService` Service
- Using a `DownloadService` Service
- Using a `FileOpenService` Service
- Using a `FileSaveService` Service
- Using a `PrintService` Service
- Using a `PersistenceService` Service
- Using `FileContents`
- Using a `JNLPRandomAccessFile`

### Introduction

The JNLP API is designed to provide additional information to the application that would otherwise not be available using the standard Java 2 SE API. The following code examples show how the following services can be used: `BasicService`, `ClipboardService`, `DownloadService`, `FileOpenService`, `FileSaveService`, `PrintService`, and `PersistenceService`.

The public classes and interfaces in the JNLP API are included in the `jnlp.jar` file. This JAR file must be included in the classpath when compiling source files that use the JNLP API. For example on Windows:

`javac -classpath .;jnlp.jar *.java`

The `jnlp.jar` file is included in the JNLP Developers Pack.

### Using a `BasicService` Service

The `javax.jnlp.BasicService` service provides a set of methods for querying and interacting with the environment similar to what the `AppletContext` provides for a Java Applet.

The `showURL` method uses the JNLP API to direct the default browser on the platform to show the given URL. The method returns true if the request succeeds, otherwise false.

`import javax.jnlp.*;`
`...`

`// Method to show a URL`
`boolean showURL(URL url) {`
`try {`
`// Lookup the javax.jnlp.BasicService object`
`BasicService bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");`
`// Invoke the showDocument method`
`return bs.showDocument(url);`
`} catch(UnavailableServiceException ue) {`
`// Service is not supported`
`return false;`
`}`
`}`

### Using a `ClipboardService` Service

The `javax.jnlp.ClipboardService` service provides methods for accessing the shared system-wide clipboard, even for applications that are running in the restricted execution environment.

Java Web Start will warn the user of the potential security risk of letting an untrusted application access potentially confidential information stored in the clipboard, or overwriting contents stored in the clipboard.

`import javax.jnlp;`
`...`

`private ClipboardService cs;`

`try {`
`cs = (ClipboardService)ServiceManager.lookup`
`("javax.jnlp.ClipboardService");`
`} catch (UnavailableServiceException e) {`
`cs = null;`
`}`

`if (cs != null) {`
`// set the system clipboard contents to a string selection`
`StringSelection ss = new StringSelection("Java Web Start!");`
`cs.setContents(ss);`
`// get the contents of the system clipboard and print them`
`Transferable tr = cs.getContents();`
`if (tr.isDataFlavorSupported(DataFlavor.stringFlavor)) {`
`try {`
`String s = (String)tr.getTransferData(DataFlavor.stringFlavor);`
`System.out.println("Clipboard contents: " + s);`
`} catch (Exception e) {`
`e.printStackTrace();`
`}`
`}`
`}`

### Using a `DownloadService` Service

The `javax.jnlp.DownloadService` service allows an application to control how its own resources are cached.

The service allows an application to determine which of its resources are cached, to force resources to be cached, and to remove resources from the cache.

    import javax.jnlp.*;
        ...

        DownloadService ds;

        try {
            ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService");
        } catch (UnavailableServiceException e) {
            ds = null;
        }

        if (ds != null) {

            try {
                // determine if a particular resource is cached
                URL url =
                        new URL("http://java.sun.com/products/javawebstart/lib/draw.jar");
                boolean cached = ds.isResourceCached(url, "1.0");
                // remove the resource from the cache
                if (cached) {
                    ds.removeResource(url, "1.0");
                }
                // reload the resource into the cache
                DownloadServiceListener dsl = ds.getDefaultProgressWindow();
                ds.loadResource(url, "1.0", dsl);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

### Using a `FileOpenService` Service

The `javax.jnlp.FileOpenService` service provides methods for importing files from the local disk, even for applications that are running in the restricted execution environment.

This interface is designed to provide the same kind of of disk access to potentially untrusted Web-deployed applications that a Web developer has when using HTML. HTML forms support the inclusion of files by displaying a file open dialog.

    import javax.jnlp.*;
        ...

        FileOpenService fos;

        try {
            fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
        } catch (UnavailableServiceException e) {
            fos = null;
        }

        if (fos != null) {
            try {
                // ask user to select a file through this service
                FileContents fc = fos.openFileDialog(null, null);
                // ask user to select multiple files through this service
                FileContents[] fcs = fos.openMultiFileDialog(null, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

### Using a `FileSaveService` Service

The `javax.jnlp.FileSaveService` service provides methods for exporting files to the local disk, even for applications that are running in the restricted execution environment.

This interface is designed to provide the same level of disk access to potentially untrusted Web-deployed applications that a Web browser provides for contents that it is displaying. Most browsers provide a Save As... dialog as part of their user interface.

    import javax.jnlp.*;
        ...

        FileSaveService fss;
        FileOpenService fos;

        try {
            fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
            fss = (FileSaveService)ServiceManager.lookup
                                       ("javax.jnlp.FileSaveService");
        } catch (UnavailableServiceException e) {
            fss = null;
            fos = null;
        }

        if (fss != null && fos != null) {
            try {
                // get a file with FileOpenService
                FileContents fc = fos.openFileDialog(null, null);
                // one way to save a file
                FileContents newfc = fss.saveFileDialog(null, null,
                fc.getInputStream(), "newFileName.txt");
                // another way to save a file
                FileContents newfc2 = fss.saveAsFileDialog(null, null, fc);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

Also see Using `FileContents`.

### Using a `PrintService` Service

The `javax.jnlp.PrintService` service provides methods for access to printing, even for applications that are running in the restricted execution environment.

Using this service, an application can submit a print job. Java Web Start will then show this request to the user and, if accepted, queue the request to the printer.

    import javax.jnlp.*;
        ...

        PrintService ps;

        try {
            ps = (PrintService)ServiceManager.lookup("javax.jnlp.PrintService");
        } catch (UnavailableServiceException e) {
            ps = null;
        }

        if (ps != null) {
            try {

                // get the default PageFormat
                PageFormat pf = ps.getDefaultPage();

                // ask the user to customize the PageFormat
                PageFormat newPf = ps.showPageFormatDialog(pf);

                // print the document with the PageFormat above
                ps.print(new DocToPrint());

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // Code to construct the Printable Document
        class DocToPrint implements Printable {
            public int print(Graphics g, PageFormat pageformat, int PageIndex){
                // code to generate what you want to print
            }
        }

### Using a `PersistenceService` Service

The `javax.jnlp.PersistenceService` service provides methods for storing data locally on the client system, even for applications that are running in the restricted execution environment.

The service is designed to be somewhat similar to that which the cookie mechanism provides to HTML-based applications. Cookies allow a small amount of data to be stored locally on the client system. That data can be securely managed by the browser and can only be retrieved by HTML pages which originate from the same URL as the page that stored the data.

    import javax.jnlp.*;
        ...

        PersistenceService ps;
        BasicService bs;

        try {
            ps = (PersistenceService)ServiceManager.lookup("javax.jnlp.PersistenceService");
            bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
        } catch (UnavailableServiceException e) {
            ps = null;
            bs = null;
        }

        if (ps != null && bs != null) {

            try {
                // find all the muffins for our URL
                URL codebase = bs.getCodeBase();
                String [] muffins = ps.getNames(url);

                // get the attributes (tags) for each of these muffins.
                // update the server's copy of the data if any muffins
                // are dirty
                int [] tags = new int[muffins.length];
                URL [] muffinURLs = new URL[muffins.length];
                for (int i = 0; i < muffins.length; i++) {
                    muffinURLs[i] = new URL(codebase.toString() + muffins[i]);
                    tags[i] = ps.getTag(muffinURLs[i]);
                    // update the server if anything is tagged DIRTY
                    if (tags[i] == PersistenceService.DIRTY) {
                        doUpdateServer(muffinURLs[i]);
                    }
                }

                // read in the contents of a muffin and then delete it
                FileContents fc = ps.get(muffinURLs[0]);
                long maxsize = fc.getMaxLength();
                byte [] buf = new byte[fc.getLength()];
                InputStream is = fc.getInputStream();
                long pos = 0;
                while((pos = is.read(buf, pos, buf.length - pos)) > 0) {
                    // just loop
                }
                is.close();

                ps.delete(muffinURLs[0]);

                // re-create the muffin and repopulate its data
                ps.create(muffinURLs[0], maxsize);
                fc = ps.get(muffinURLs[0]);
                // don't append
                OutputStream os = fc.getOutputStream(false);
                os.write(buf);
                os.close();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

       void doUpdateServer(URL url) {
            // update the server's copy of the persistent data
            // represented by the given URL
            ...
            ps.setTag(url, PersistenceService.CACHED);
       }

### Using `FileContents`

`javax.jnlp.FileContents` objects encapsulate the name and contents of a file. An object of this class is used by the `FileOpenService,` `FileSaveService` and`PersistenceService`. Here is an example of how an instance of a `FileContents` can be used to read from and write to a file:

    import javax.jnlp.*;
        ...

        FileOpenService fos;

        //Initialize fos (see Using a FileOpenService Service example)
        ...

        if (fos != null) {

            try {

                // get a FileContents object to work with from the
                // FileOpenService
                FileContents fc = fos.openFileDialog(null, null);

                // get the InputStream from the file and read a few bytes
                byte [] buf = new byte[fc.getLength()];
                InputStream is = fc.getInputStream();
                int pos = 0;
                while ((pos = is.read(buf, pos, buf.length - pos)) > 0) {
                    // just loop
                }
                is.close();

                // get the OutputStream and write the file back out
                if (fc.canWrite()) {
                   // don't append
                   OutputStream os = fc.getOutputStream(false);
                   os.write(buf);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

### Using a `JNLPRandomAccessFile`

Instances of `javax.jnlp.JNLPRandomAccessFile` support both reading and writing to a random access file. A random access file behaves like a large array of bytes stored in the file system. Here is an example of how an instance of a `JNLPRandomAccessFile` can be used to write to a random access file:

    import javax.jnlp.*;
        ...

        FileOpenService fos;

        //Initialize fos (see Using a FileOpenService Service example)
        ...

        if (fos != null) {
            try {
               // ask the user to choose a file to open
               FileContents fc = fos.openFileDialog(null, null);

               // attempt to increase the maximum file length
               long grantedLength = fc.getLength();
               if (grantedLength + 1024 > fc.getMaxLength()) {
                   // attempt to increase the maximum file size defined by
                   // the client
                   grantedLength = fc.setMaxLength(grantedLength + 1024);
               }

               // if we were able to increase the maximum allowable file size,
               // get a JNLPRandomAccessFile representation of the file, and
               // write to it
               if (fc.getMaxSize() > fc.getLength() && fc.canWrite()) {
                   JNLPRandomAccessFile raf = fc.getRandomAccessFile("rw");
                   raf.seek(raf.length() - 1);
                   raf.writeUTF("Java Web Start!");
                   raf.close();
               }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }