001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.hayabusa.io;
017
018import javax.swing.tree.TreeModel;
019import javax.swing.tree.DefaultTreeModel;
020import javax.swing.tree.TreeNode;
021import javax.swing.tree.DefaultMutableTreeNode;
022import java.io.File;
023
024/**
025 * 内部に TreeModel を持ったファイル階層表現を表すクラスです。
026 * ルートディレクトリを指定して、それ以下のディレクトリ階層を構築します。
027 * このクラスは、すべてのデータを走査してから、TreeModel を構築しますので、
028 * パフォーマンス的には劣ります。
029 *
030 * @og.group その他出力
031 *
032 * @version  4.0
033 * @author   Kazuhiko Hasegawa
034 * @since    JDK5.0,
035 */
036public class FileTreeModel {
037        private TreeModel       model   ;                       // 6.3.9.1 (2015/11/27) 修飾子を、なし → private に変更。
038
039        /**
040         * デフォルトコンストラクター
041         *
042         */
043        public FileTreeModel() {
044                initialise( null );
045        }
046
047        /**
048         * ルートディレクトリを指定して、TreeModel を構築するコンストラクター
049         *
050         * @param   dir ルートディレクトリ文字列
051         */
052        public FileTreeModel( final String dir ) {
053                initialise( dir );
054        }
055
056        /**
057         * ルートディレクトリを指定して、TreeModel を構築します。
058         *
059         * @param   dir ルートディレクトリ文字列
060         */
061        public void setDirectory( final String dir ) {
062                initialise( dir );
063        }
064
065        /**
066         * ルートディレクトリを指定して、TreeModel を構築します。
067         *
068         * @og.rev 6.4.1.2 (2016/01/22) インスタンス変数の dir は、未使用なので、削除
069         *
070         * @param   dir ルートディレクトリ文字列
071         */
072        private void initialise( final String dir ) {
073                final String rootDir = dir == null ? "." : dir ;
074
075                final TreeNode root = makeTree( new File( rootDir ) );
076                model = new DefaultTreeModel( root );
077        }
078
079        /**
080         * TreeModel を取得します。
081         * コンストラクター または、setDirectory()メソッドによって構築された
082         * ディレクトリ階層を TreeModel にマッピングして返します。
083         *
084         * @return      ルートディレクトリ文字列
085         */
086        public TreeModel getTreeModel() {
087                return model;
088        }
089
090        /**
091         * 内部的に ディレクトリ階層を表現した TreeNode を返します。
092         *
093         * @param       dir             ルートディレクトリのファイルオブジェクト
094         *
095         * @return      ディレクトリ階層を表現したTreeNode
096         */
097        private DefaultMutableTreeNode makeTree( final File dir ) {
098                final DefaultMutableTreeNode node = new DefaultMutableTreeNode( dir.getName() );
099                if( dir.isDirectory() ) {
100                        final String[] list = dir.list();
101                        // 6.3.9.0 (2015/11/06) null になっている可能性がある(findbugs)
102                        if( list != null ) {
103                                for( final String file : list ) {
104                                        node.add( makeTree( new File( dir, file ) ) );
105                                }
106                        }
107                }
108                return node;
109        }
110
111        /**
112         * Tree の表示用メソッド
113         *
114         * これは、テスト用に使用するための Tree を標準出力に 出力するメソッドです。
115         *
116         * @og.rev 8.5.6.1 (2024/03/29) 配列にセットするのを止める。
117         *
118         * @param    root       トップレベルのTreeNodeオブジェクト(階層的に印字します。)
119         * @param    model      TreeNodeを含む TreeModelオブジェクト
120         * @param    level      階層レベル。一番トップを 0 レベルとする。
121         */
122        public void printTree( final TreeNode root,final TreeModel model,final int level ) {
123                final int num = model.getChildCount( root );
124//              final TreeNode[] nodes = new TreeNode[num];             // 8.5.4.2 (2024/01/12) PMD 7.0.0 LocalVariableCouldBeFinal
125//              for( int i=0; i<num; i++ ) {
126//                      nodes[i] = (TreeNode)model.getChild( root,i );
127//                      if( nodes[i].isLeaf() ) {
128//                              System.out.println( level + ":" + nodes[i].toString() );
129//                      }
130//                      else {
131//                              System.out.println( level + ":" + nodes[i].toString() );
132//                              printTree( nodes[i],model,level+1 );
133//                      }
134//              }
135
136                for( int i=0; i<num; i++ ) {
137                        final TreeNode node = (TreeNode)model.getChild( root,i );
138                        if( node.isLeaf() ) {
139                                System.out.println( level + ":" + node.toString() );
140                        }
141                        else {
142                                System.out.println( level + ":" + node.toString() );
143                                printTree( node,model,level+1 );
144                        }
145                }
146        }
147
148        /**
149         * main メソッド
150         *
151         * これは、テスト用に使用するための main メソッドです。
152         *
153         * @param  args  起動時の引数 args[0] にルートディレクトリ名
154         */
155        public static void main( final String[] args ) {
156                final FileTreeModel fmodel = new FileTreeModel( args[0] );
157                final TreeModel model = fmodel.getTreeModel();
158                final TreeNode root = (TreeNode)model.getRoot() ;
159                fmodel.printTree( root,model,0 );
160        }
161}