OSDN Git Service

srcディレクトリとdocディレクトリを作成
[xdf/git-repos.git] / src / xdf / src / main / java / jp / ac / aiit / xdf / application / Application.java
1 package jp.ac.aiit.xdf.application;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.InputStream;
7 import java.net.URISyntaxException;
8 import java.net.URL;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13
14 import jp.ac.aiit.xdf.application.interceptors.UIDesignInterceptingManager;
15 import jp.ac.aiit.xdf.application.interceptors.UIDesignResource;
16 import jp.ac.aiit.xdf.component.common.CommonTagReferences;
17 import jp.ac.aiit.xdf.core.action.factory.ActionFactory;
18 import jp.ac.aiit.xdf.core.action.factory.DefaultActionFactory;
19 import jp.ac.aiit.xdf.core.exceptions.UnexpectedBehaviorException;
20 import jp.ac.aiit.xdf.core.model.ObjectModel;
21 import jp.ac.aiit.xdf.core.selector.Selector;
22 import jp.ac.aiit.xdf.core.tags.Tagdef.Tag;
23
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * 本フレームワークで作成されたアプリケーションを管理するクラス
29  * プラグイン提供されたコンポーネント群やアクションインスタンスの生成方法などを設定することができる
30  * なお、本クラスはSigletonになっているため、インスタンスの取得にはgetInstanceメソッドを用いること
31  * 
32  * @author Shunichi Takagi
33  */
34 public class Application {
35         private static final Logger log = LoggerFactory.getLogger(Application.class);
36         
37         /**
38          * アプリケーションのインスタンス
39          */
40         public static final Application instance = new Application();
41         
42         private Application(){
43                 this.toolkit = "swing";
44                 this.definedTags = new HashMap<String, Tag>();
45                 this.factory = new DefaultActionFactory();
46                 this.windows = new HashMap<String, InputStream>();
47                 
48                 this.refs = new ArrayList<TagReferences>();
49                 useTags(new CommonTagReferences());
50                 
51                 this.openedWindows = new HashMap<String, ObjectModel>();
52         }
53         
54         private LifeCycle lifeCycle = new DefaultLifeCycle();
55         
56         private String toolkit;
57         private Map<String, Tag> definedTags;
58         private Map<String, InputStream> windows;
59         
60         private ActionFactory factory;
61         private List<TagReferences> refs;
62         
63         private Map<String, ObjectModel> openedWindows;
64         
65         /**
66          * アプリケーションのインスタンス取得メソッド
67          * @return シングルトン化されたApplicationのインスタンス
68          */
69         public static Application getInstance() {
70                 return instance;
71         }
72         
73         /**
74          * アプリケーションのインスタンス取得メソッド
75          * 引数で与えられたタグ参照の読み込みをインスタンス取得と同時に行う
76          * 
77          * @param refs このアプリケーションで利用するタグ参照の固まり。プラグインによって提供される
78          * @return アプリケーションのインスタンス
79          */
80         public static Application getInstance(TagReferences ...refs) {
81                 for(TagReferences ref : refs) {
82                         instance.useTags(ref);
83                 }
84                 return instance;
85         }
86         
87         /**
88          * このアプリケーションに対するライフサイクルを設定
89          * 
90          * @param lifeCycle このアプリケーションに設定されるライフサイクル
91          */
92         public void setLifeCycle(LifeCycle lifeCycle) {
93                 this.lifeCycle = lifeCycle;
94         }
95         /**
96          * このアプリケーションを実行するツールキット環境を設定する
97          * @param toolkit
98          */
99         public void setToolkit(String toolkit) {
100                 this.toolkit = toolkit;
101         }
102         
103         /**
104          * このアプリケーションを実行するツールキット環境名を取得する
105          * @return ツールキット環境名
106          */
107         public String getToolkit() {
108                 return toolkit;
109         }
110         
111         /**
112          * アプリケーション内で使用するタグを追加する
113          * @param refs
114          */
115         public void useTags(TagReferences refs) {
116                 this.refs.add(refs);
117                 this.definedTags = mergeTags(definedTags, refs.getDefinedTags());
118         }
119         
120         /**
121          * アプリケーション内で利用されるActionをインスタンス化するための方法を設定する
122          * @param factory アクションのインスタンス生成ファクトリ
123          */
124         public void setActionFactory(ActionFactory factory) {
125                 this.factory = factory;
126         }
127         
128         /**
129          * アプリケーション内でアクションのインスタンス化に使用されるファクトリを取得
130          * @return アクションファクトリのインスタンス
131          */
132         public ActionFactory getActionFactory() {
133                 return factory;
134         }
135         
136         /**
137          * アプリケーションにウィンドウを追加する
138          * 
139          * @param name ウィンドウ名
140          * @param uidesign ウィンドウ定義ファイルへのClasspath上のパス
141          * @throws FileNotFoundException 指定されたファイルが見つからなかった場合にthrowされる
142          */
143         public void registWindow(String name, String uidesign) throws FileNotFoundException {
144                 URL url = ClassLoader.getSystemResource(uidesign);
145                 
146                 if( url == null ) {
147                         log.warn("指定された画面定義XMLファイルが見つかりません file:"+uidesign);
148                         throw new FileNotFoundException("指定された画面定義XMLファイルが見つかりません file:"+uidesign);
149                 } else {
150                         try {
151                                 windows.put(name, new FileInputStream( new File( url.toURI() ) ));
152                         } catch (URISyntaxException e) {
153                                 log.warn("フレームワーク内部で予期しない例外が発生しました。", e);
154                                 throw new UnexpectedBehaviorException("フレームワーク内部で予期しない例外が発生しました。", e);
155                         }
156                 }
157         }
158         
159         /**
160          * アプリケーションにウィンドウを追加する
161          * 
162          * @param name ウィンドウ名
163          * @param uidesign ウィンドウ定義ファイルを読み込むためのストリーム
164          */
165         public void registWindow(String name, InputStream uidesign) {
166                 windows.put(name, uidesign);
167         }
168         
169         /**
170          * 指定した名前のウィンドウを起動する
171          * 
172          * @param name 起動するウィンドウの名前
173          */
174         public void open(String name) {
175                 if( windows.containsKey(name) ) {
176                         if( openedWindows.size() == 0 ) {
177                                 lifeCycle.launch();
178                         }
179                         lifeCycle.beforeOpened(name);
180                         
181                         InputStream inputStream = windows.get(name);
182                         
183                         UIDesignResource resource = new UIDesignResource(inputStream, definedTags);
184                         UIDesignInterceptingManager manager = UIDesignInterceptingManager.getDefaultManager();
185                         manager.invoke(resource);
186                         
187                         ObjectModel model = resource.getModel();
188                         model.attr("windowName", name);
189                         
190                         for (ObjectModel menuModel: new Selector("menugroup").find(model)){
191                                 menuModel.realize();
192                         }
193                         
194                         ObjectModel frameModel = new Selector("frame").find(model).get(0);
195                         frameModel.realize();
196                         
197                         frameModel.open();
198                         
199                         openedWindows.put(name, model);
200                         
201                         lifeCycle.afterOpened(name);
202                 } else {
203                         log.warn("指定された名前のウィンドウは登録されていません name:"+name);
204                 }
205         }
206         
207         /**
208          * 指定した名前のウィンドウを閉じる
209          * 
210          * @param name 閉じるウィンドウの名前
211          */
212         public void close(String name) {
213                 if( openedWindows.containsKey(name) ) {
214                         lifeCycle.beforeClosed(name);
215                         
216                         ObjectModel model = openedWindows.get(name);
217                         openedWindows.remove(name);
218                         
219                         ObjectModel frameModel = new Selector("frame").find(model).get(0);
220                         frameModel.close();
221                         
222                         lifeCycle.afterClosed(name);
223                         if( openedWindows.size() == 0 ) {
224                                 lifeCycle.shutdown();
225                         }
226                 } else {
227                         log.info("指定されたウィンドウは登録されていないか既に閉じられています。 name:"+name);
228                 }
229         }
230         
231         private Map<String,Tag> mergeTags(Map<String,Tag> arg0, Map<String,Tag> arg1) {
232                 for(String tagname1 : arg1.keySet()) {
233                         if( arg0.containsKey(tagname1) ) {
234                                 Tag tag0 = arg0.get(tagname1);
235                                 Tag tag1 = arg1.get(tagname1);
236                                 
237                                 tag0.merge(tag1);
238                         } else {
239                                 arg0.put(tagname1, arg1.get(tagname1));
240                                 log.info(tagname1+":"+arg1.get(tagname1));
241                         }
242                 }
243                 
244                 return arg0;
245         }
246         
247         /**
248          * アプリケーションインスタンスからウィンドウ登録名にてウィンドウオブジェクトモデルを取得する
249          * @param name
250          * @return オブジェクトモデル
251          */
252         public ObjectModel getWindow(String name){
253                 return this.openedWindows.get(name); 
254         }
255
256         /**
257          * 指定されたウィンドウにあるIDのコンポーネントを検索する
258          * 
259          * @param window ウィンドウ登録名
260          * @param id コンポーネントID
261          * @return コンポーネントオブジェクト
262          */
263         public static ObjectModel findById(String window, String id){
264                 return Selector.find("#" + id, Application.getInstance().getWindow(window)).get(0);
265         }
266
267         /**
268          * 指定されたウィンドウのコンポーネントをセレクタ構文を用いて検索する
269          * 
270          * @param window ウィンドウ登録名
271          * @param selector コンポーネント検索用セレクタ
272          * @return コンポーネントオブジェクト
273          */
274         public static List<ObjectModel> findBySelector(String window, String selector) {
275                 return Selector.find(selector, Application.getInstance().getWindow(window));
276         }
277 }