SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Jakarta Commonsを使ってJDKクラスを拡張する:パート3

Commons CLI/VFS/Configuration/Poolの利用

VFS

 Commons Virtual File System(VFS)は、さまざまな種類のファイルシステムに統一された方法でアクセスするための抽象化レイヤを提供しています。このコンポーネントを使えば、1つまたは複数のファイルシステムに同時に接続できます。これはLinuxオペレーティングシステムのmount機能に似ています。

 VFSがサポートするファイルシステムは次のとおりです。

  • ローカルファイル ― ローカルのファイルおよびフォルダ(file://)
  • zip、jar、tar、tgz、tbz2、gzip、bzip2 ― 多様な圧縮形式を透過的に処理可能(zip://、jar://、など)
  • CIFS ― sambaサーバーまたはWindowsの共有ファイル(smb://)
  • FTP ― FTPサーバー(ftp://)
  • HTTPおよびHTTPS(http://)
  • SFTP ― SSHまたはSCPサーバー(sftp://)
  • テンポラリファイル(tmp://)
  • WebDAV ― Web-based Distributed Authoring and Versioning(webdav://)
  • クロスローダの提供するリソース ― ローディングクラスまたはクラスローダを使った他のリソース(res://)

 サポートされているプロトコルURIの完全な構文についてはこちらを、高レベルでのこのAPIの用法についてはこちらをご覧ください。

 このコンポーネントは、種類の異なるファイルに対してシームレスにアクセスする必要があるアプリケーションで非常に役立ちます。たとえば、デスクトップ検索ツールがその代表的な例です。ユーザーは、デスクトップ検索ツールを使って、さまざまな形式のファイルから特定のファイルまたはファイルコンテンツを検索します。Windows Explorerのような機能をJavaアプリケーションに組み込む場合にもこのコンポーネントが利用できます。

 ここで紹介するサンプルアプリケーションでは、Commons VFSを利用して、フォルダだけでなくzipおよびjarファイルにも対応した検索を行います。このサンプルにユーザーインターフェイスはありませんが、テストケースを使ってその動作を確認できます。このサンプルとテストケースは「in.co.narayanan.commons.vfs」パッケージに含まれています。サンプルアプリケーションを実行するには、ソースアーカイブをダウンロードしてCommon VFSライブラリ作成用のAntビルドスクリプトを実行します。このAntスクリプトは、依存関係のある他のライブラリファイルもダウンロードできる優れモノです。in.co.narayanan.commons.vfs.TestSearchBuddyというJUnitテストケースクラスを実行するとサンプルアプリケーションが起動します。

 TCommons VFSを用いる基本的な考え方は、サポートされているファイルの種類ごとにプロバイダを作成して、DefautFileSystemManagerのインスタンス(以降はマネージャとして参照されます)に追加するというものです。以降の処理では、managerresolveFileメソッドを使って、該当するFileObjectのインスタンスへの参照を取得する必要があります。このmanagerFileObjectには他にも役に立つメソッドがたくさんあるので、javadocを読んでおいて損はありません。以降では、検索ツールにおけるCommons VFS APIの使い方を説明します。

 リスト6は、DefaultFileSystemManagerクラスの初期化に用いるin.co.narayanan.commons.vfs.SearchBuddyクラスのコードの一部です。

リスト6 ファイルシステムマネージャの初期化
/**
 * Initialize the DefaultFileSystemManager to support
 * file, zip and jar providers. A virtual file system
 * is created and passed to the SearchableVirtualFileSystem
 * decorator class.
 *
 * @throws SearchException Error in initializing the file
 *                         FileSystemManager
 */
private void init() throws SearchException {
    defFileSysMgr = new DefaultFileSystemManager();

    try {

        defFileSysMgr.addProvider(
            "file", new DefaultLocalFileProvider());
        defFileSysMgr.addProvider(
            "zip", new ZipFileProvider());
        defFileSysMgr.addProvider(
            "jar", new JarFileProvider());
        defFileSysMgr.init();

        // Create the virtual file system
        VirtualFileSystem vfs = 
        (VirtualFileSystem)defFileSysMgr
            .createVirtualFileSystem("vfs://").getFileSystem();

        searchableVfs = new SearchableVirtualFileSystem(vfs);

    } catch (FileSystemException e) {
        throw new SearchException(
            "Unable to initialize the FileSystemManager.", e);
    }
}

 太字の部分は、ローカルファイルシステム、zipファイル、jarファイルを検索するためのプロバイダを追加するコードです。このコードはVirtualFileSystemクラスのインスタンスを作成します。作成したインスタンスは他のファイルシステムのマウントに使用されます(この詳細とSearchableVirtualFileSystemクラスについては後述)。

 リスト7は、テストケースクラスTestSearchBuddyの一部です。このコードは、サンプルアプリケーションを使ってどのようにファイル検索を行うかを示しています。

リスト7 検索ツールの使い方
/**
 * Adds the folder, zip, and a jar file to search
 * 
 * @throws Exception Error in the test.
 */
public void testSearchInZips() throws Exception {
    SearchBuddy searchTool = new SearchBuddy();
    searchTool.addSearchableZip("testroot.zip");
    searchTool.addSearchableJar("testjar.jar");
    searchTool.addSearchableFolder(".");
        
    System.out.println("Searching for news.txt");
    searchTool.search("news", "txt");
        
    System.out.println("Searching for Range.class");
    searchTool.search("range", "class");
        
    System.out.println("Searching for test.xml");
    searchTool.search("test", "xml");
 
    System.out.println("Searching for *.properties");
    searchTool.search(null, "properties");
    searchTool.close();
} 

 太字の行は、検索対象のzipファイルとjarファイルを追加する部分です。このsearchメソッドの呼び出し時には、検索するファイル名と拡張子を与えます。

 リスト8は、SearchBuddyクラスのコードの一部です。このコードは、各種ファイルを仮想ファイルシステムにマウントする方法を示しています。

リスト8 zipファイルを仮想ファイルシステムにマウントするコード
/**
 * Mount a zip file to the searchable virtual
 * file system.
 *
 * @param pathToFolder Absolute or relative path to the zip file.
 * @throws SearchException Error while adding the zip file
 *         to the virtual file system.
 */
public void addSearchableZip(String pathToZip)
    throws SearchException {
    File zipFile = new File(pathToZip);
    if(!zipFile.exists()) {
        throw new SearchException("Invalid zip file path");
    }
    try {
        FileObject zipFileObject = defFileSysMgr.toFileObject(zipFile);
        searchableVfs.addJunction("/" + zipFile,
            defFileSysMgr.resolveFile("zip:" + zipFileObject + "!/"));
    } catch (FileSystemException e) {
        throw new SearchException(
            "Unable to add zip file to the virtual file system", e);
    }
}

 このzipファイルのマウントは、VirtualFileSystemクラスのaddJunctionメソッドを呼び出すことで行われます。この接合箇所(またはマウントポイント)はデコレータクラスSearchableVirtualFileSystemにキャッシュされ、後の検索処理で呼び出されます。

 リスト9は、マウントされたファイルシステムを検索するコードです。

リスト9 検索処理
Class SearchBuddy
/**
 * Delegate the search call to the Searchable virtual file
 * system decorator.
 *
 * @param fileNamePart Name of the file.
 * @param extension Extension to search
 * @throws SearchException Error from the VirtualFileSystem
           when searching for file.
 */
public void search(String fileNamePart, String extension)
    throws SearchException {
    searchableVfs.search(fileNamePart, extension);
}

Class SearchableVirtualFileSystem
/**
 * Iterate the junctions to search for the given file name.
 *
 * @param fileNamePart File name to search
 * @param extension Extension to search
 * @throws SearchException
 */
public void search(String fileNamePart, String extension)
    throws SearchException {
    try {
        Iterator<String> searchPoints = junctions.iterator();
        FileObject matchingFiles[];
        while(searchPoints.hasNext()) {
            String searchPoint = searchPoints.next();
            FileObject searchRoot = vfs.resolveFile(searchPoint);
            filter.setExtension(extension);
            filter.setFileNamePart(fileNamePart);
            matchingFiles = searchRoot.findFiles(filter);
            for(FileObject file : matchingFiles) {
                System.out.println("Result:" + file);
            }
        }
    } catch (FileSystemException e) {
        throw new SearchException("Search failed", e);
    }
}

 このsearchメソッドは、マウントされたファイルシステムに対して繰り返し処理を行い、ルートを特定して、FileObjectクラスのfindFilesメソッドを検索フィルタ付きで呼び出します。検索結果はコンソールに出力されます。このデコレータクラスSearchableVirtualFileSystemの主な役割は、マウントされたファイルシステムを記憶しておくことです。他のメソッドを呼び出す権限は、ラップされたVirtualFileSystemのインスタンスに委譲されます。

 このサンプルアプリケーションのソースファイルには、説明用のコメントが十分に書かれているので、詳しくはそちらをご覧ください。

 Common VFSのフレームワークをデスクトップおよびサーバーアプリケーションに用いれば、コンシューマプログラムとファイルタイプ固有のコードとを完全に分離できます。その結果、アプリケーションのモジュール性が高まり、開発が容易になります。

次のページ
Configuration

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Narayanan A.R.(Narayanan A.R.)

テスト駆動開発、アジャイル方法論、Javaテクノロジ、およびデザインパターンの熱烈な擁護者。Javaテクノロジを使ったソフトウェアのデザインおよび開発に携わって数年になる。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/313 2006/04/11 19:10

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー