JNLP API 의 사용예 - xrath.com 에서 번역됨

# JNLP API 의 사용예

이 장에서는, 다음의 토픽에 대해 설명합니다.

- 처음에
- `BasicService` 서비스의 사용법
- `ClipboardService` 서비스의 사용법
- `DownloadService` 서비스의 사용법
- `FileOpenService` 서비스의 사용법
- `FileSaveService` 서비스의 사용법
- `PrintService` 서비스의 사용법
- `PersistenceService` 서비스의 사용법
- `FileContents` 의 사용법
- `JNLPRandomAccessFile` 의 사용법
- `SingleInstanceService` 서비스의 사용법
- `ExtendedService` 서비스의 사용법

### 처음에

JNLP API 의 목적은, 표준의 Java(TM) Platform Standard Edition API 경유에서는 입수 불가능한 추가 정보를, 어플리케이션에 대해서 제공하는 것입니다. 다음에 드는 샘플 코드는, 서비스 `BasicService`,`ClipboardService`,`DownloadService`,`FileOpenService`,`FileSaveService`,`PrintService`, 및 `PersistenceService` 의 사용법을 나타낸 것입니다.

JNLP API 의 공개 클래스와 인터페이스는,`jnlp.jar` 파일내에 넣을 수 있고 있습니다. JNLP API 를 사용하고 있는 원시 파일을 컴파일 하려면 , 이 JAR 파일을 클래스 패스에 포함할 필요가 있습니다. 예를 들어, Windows 상에서는 다음과 같이 합니다.

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

`jnlp.jar` 파일은, JNLP 개발자전용 팩에 포함되어 있습니다.

### `BasicService` 서비스의 사용법

`javax.jnlp.BasicService` 서비스가 제공하는 일련의 메소드를 사용하면, 환경에 대한 문의나 대화를 실시할 수 있습니다. 이러한 메소드는,`AppletContext` 가 Java 애플릿에 대해서 제공하는 메소드를 닮아 있습니다.

`showURL` 메소드는 JNLP API 를 사용해, 플랫폼상의 디폴트 브라우저에 대해, 지정된 URL 를 표시하도록 지시합니다. 이 메소드는, 요구가 성공했을 경우에는 true 를 돌려주어, 그렇지 않은 경우에는 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;`
`}`
`}`

### `ClipboardService` 서비스의 사용법

`javax.jnlp.ClipboardService` 서비스가 제공하는 메소드를 사용하면, 시스템 전체의 공유 클립보드에 액세스 할 수 있습니다. 이 서비스는, 제한된 런타임내에서 동작중의 어플리케이션으로부터에서도 이용 가능합니다.

Java Web Start 는, 클립보드에 포함되고 있는 내용 (기밀 정보가 포함될 가능성도 있다)에의 액세스나, 그러한 내용의 덧쓰기를 신뢰할 수 없는 어플리케이션에 허가되면(자), 시큐리티상의 문제가 발생할 가능성이 있는 것을 사용자에게 경고합니다.

`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();`
`}`
`}`
`}`

### `DownloadService` 서비스의 사용법

`javax.jnlp.DownloadService` 서비스를 사용하면, 어플리케이션은 자신의 자원을 어떻게 캐쉬하는지를 제어할 수 있습니다.

어플리케이션은 이 서비스를 사용하는 것으로, 어느 자원이 캐쉬되고 있을까의 확인, 자원의 강제 캐쉬, 및 캐쉬로부터의 자원의 삭제를 실시할 수 있습니다.

    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();
            }
        }

### `FileOpenService` 서비스의 사용법

`javax.jnlp.FileOpenService` 서비스가 제공하는 메소드를 사용하면, 로컬 디스크로부터 파일을 임포트 할 수 있습니다. 이 서비스는, 제한된 런타임내에서 동작중의 어플리케이션으로부터에서도 이용 가능합니다.

이 인터페이스의 목적은, HTML 사용시에 Web 개발자에 대해서 제공되는 것과 같은 종류의 디스크 액세스 기능을, 신뢰할 수 없을 가능성이 있는 Web 배치 어플리케이션에 대해서 제공하는 것입니다. HTML 폼은, 파일 선택 다이얼로그에 의한 파일의 편입을 지원하고 있습니다.

    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();
            }
        }

### `FileSaveService` 서비스의 사용법

`javax.jnlp.FileSaveService` 서비스가 제공하는 메소드를 사용하면, 파일을 로컬 디스크에 export 할 수 있습니다. 이 서비스는, 제한된 런타임내에서 동작중의 어플리케이션으로부터에서도 이용 가능합니다.

이 인터페이스의 목적은, Web 브라우저가 표시중의 내용에 관해서 제공하는 것과 동레벨의 디스크 액세스 기능을, 신뢰할 수 없을 가능성이 있는 Web 배치 어플리케이션에 대해서 제공하는 것입니다. 대부분의 브라우저는, 별명 보존 다이얼로그를 사용자 인터페이스의 일부로서 제공하고 있습니다.

    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();
            }
        }

「`FileContents` 의 사용법」도 참조해 주세요.

### `PrintService` 서비스의 사용법

`javax.jnlp.PrintService` 서비스가 제공하는 메소드를 사용하면, 인쇄 기능에 액세스 할 수 있습니다. 이 서비스는, 제한된 런타임내에서 동작중의 어플리케이션으로부터에서도 이용 가능합니다.

어플리케이션은 이 서비스를 사용하는 것으로, 인쇄 작업을 발행할 수 있습니다. Java Web Start 는, 그 요구를 사용자에게 표시해, 사용자에 의해 승인되면(자), 그 요구를 프린터의 큐에 추가합니다.

Java Web Start 5.0 에서는, 직접 Java Printing API 를 사용할 수 있게 되었습니다. 샌드 박스로 어플리케이션이 실행되고 있는 경우, 이 API 를 기동하면(자),`PrintPermission` 의 부여를 사용자에게 확인하는 시큐리티 다이얼로그가 표시됩니다. JNLP Printing API 를 사용할 필요는 없어졌습니다. 어느 JNLP 어플리케이션에서도, Java Printing API 에 풀 액세스 할 수 있습니다.

    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
            }
        }

### `PersistenceService` 서비스의 사용법

`javax.jnlp.PersistenceService` 서비스가 제공하는 메소드를 사용하면, 로컬의 클라이언트 시스템상에 데이터를 포함할 수 있습니다. 이 서비스는, 제한된 런타임내에서 동작중의 어플리케이션으로부터에서도 이용 가능합니다.

이 서비스의 설계는, cookie 기구가 HTML 베이스의 어플리케이션에 제공하는 서비스에 약간 닮았습니다. cookie 를 사용하면(자), 소량의 데이터를 로컬의 클라이언트 시스템에 보존할 수 있습니다. 그 데이터는 브라우저에 의해 안전하게 관리되어 같은 URL 의 HTML 페이지를 참조하는 경우에게만 그 보존된 데이터가 사용됩니다.

    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);
       }

### `FileContents` 의 사용법

`javax.jnlp.FileContents` 객체는, 파일의 이름과 내용을 캡슐화합니다. 이 클래스의 객체는,`FileOpenService`,`FileSaveService`, 및 `PersistenceService` 에 의해 사용됩니다. 다음의 샘플 코드는,`FileContents` 의 인스턴스를 사용해 파일에 대한 읽고 쓰기를 실시하는 방법을 나타낸 것입니다.

    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();
            }
        }

### `JNLPRandomAccessFile` 의 사용법

`javax.jnlp.JNLPRandomAccessFile` 의 인스턴스는, 랜덤 억세스 파일에 대한 읽기와 기입의 양쪽 모두를 지원합니다. 랜덤 억세스 파일의 동작은, 파일 시스템에 포함된 대규모 바이트 배열의 동작을 닮아 있습니다. 다음의 샘플 코드는,`JNLPRandomAccessFile` 의 인스턴스를 사용해 랜덤 억세스 파일에 대한 기입을 실시하는 방법을 나타낸 것입니다.

    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();
            }
        }

### `SingleInstanceService` 서비스의 사용법

`javax.jnlp.SingleInstanceService` 의 제공하는 일련의 메소드를 사용하면, 어플리케이션은 자신을 단독으로 등록할 수가 있습니다. 또, 어플리케이션이 다른 인스턴스로부터 건네받은 인수를 처리하기 위한 청취자를 등록할 수 있습니다.

    import javax.jnlp. *;
        ...

        SingleInstanceService sis;

        ...

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

        ...

        // Register the single instance listener at the start of your application

        SISListener sisL = new SISListener();
        sis.addSingleInstanceListener(sisL);

        ...

        // Remember to remove the listener before your application exits

        sis.removeSingleInstanceListener(sisL);
        System.exit(0);

        // Implement the SingleInstanceListener for your application

        class SISListener implements SingleInstanceListener {
            public void newActivation(String[] params) {

                // your code to handle the new arguments here

                ...
            }
        }

### `ExtendedService` 서비스의 사용법

`javax.jnlp.ExtendedService` 는, 현재의 JNLP API 지원를 강화합니다. 이 서비스를 사용하면(자), 클라이언트의 파일 시스템으로, 어플리케이션에 의해 특정의 파일이 열립니다.

    import javax.jnlp. *;
        ...

        ExtendedService es;

        ...

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

        ...

        // Open a specific file in the local machine

        File a = new File("c:\somefile.txt");

        ...

        // Java Web Start will pop up a dialog asking the user to grant permission
        // to read/write the file c:\somefile.txt

        FileContents fc_a = es.openFile(a);

        // You can now use the FileContents object to read/write the file

        ...

        // Open a specific set of files in the local machine

        File[2] fArray = new File[2];

        fArray[0] = a;
        fArray[1] = new File("c:\anotherFile.txt");

        // Java Web Start will pop up a dialog asking the user to grant permission
        // to read/write files in fArray

        FileContents[] fc_Array = es.OpenFiles(fArray);

        // You can now read/write the set of files in fc_Array using the
        // FileContents objects

        }

`javaws` 의 사용법의 자세한 것은,「javaws 커멘드행 인터페이스」를 참조해 주세요.