OSDN Git Service

AppliStation-GUI,インストールダイアログでの表示処理等の整理
[applistation/AppliStation.git] / na-get-lib / NaGet.Packages / PackageListsManager.cs
1 using System;\r
2 using System.IO;\r
3 using System.Collections.Generic;\r
4 using NaGet.Packages;\r
5 using NaGet.Packages.Install;\r
6 \r
7 namespace NaGet.Packages\r
8 {\r
9         /// <summary>\r
10         /// パッケージリスト達をひとまとめにして管理する\r
11         /// </summary>\r
12         public class PackageListsManager\r
13         {\r
14                 internal PackageList<Package> availablePkgList;\r
15                 internal PackageList<InstalledPackage> installedPkgList;\r
16                 internal PackageList<InstalledPackage> systemInstalledPkgList;\r
17                 \r
18                 /// <summary>\r
19                 /// ファイルリストから読み込まれたパッケージのリスト\r
20                 /// </summary>\r
21                 public PackageList<Package> AvailablePkgList {\r
22                         get { return availablePkgList; }\r
23                 }\r
24                 \r
25                 /// <summary>\r
26                 /// 本ソフトウェアを介してインストールされたパッケージのリスト\r
27                 /// </summary>\r
28                 public PackageList<InstalledPackage> InstalledPkgList {\r
29                         get { return installedPkgList; }\r
30                 }\r
31                 \r
32                 /// <summary>\r
33                 /// システムから検出されたパッケージのリスト\r
34                 /// </summary>\r
35                 public PackageList<InstalledPackage> SystemInstalledPkgList {\r
36                         get { return systemInstalledPkgList; }\r
37                 }\r
38                 \r
39                 /// <summary>\r
40                 /// インストールログ\r
41                 /// </summary>\r
42                 private List<InstallationLog> systemInstalledLogList;\r
43                 \r
44                 /// <summary>\r
45                 /// 初期化をする。ファイル群を読み込んで更新がなされる。\r
46                 /// </summary>\r
47                 public PackageListsManager()\r
48                 {\r
49                         LoadPackageLists();\r
50                 }\r
51                 \r
52                 #region ファイル読み書き\r
53                 \r
54                 /// <summary>\r
55                 /// ファイルを読み込んで更新する\r
56                 /// </summary>\r
57                 public void LoadPackageLists()\r
58                 {\r
59                         try {\r
60                                 availablePkgList = NaGet.Utils.GetDeserializedObject<PackageList<Package>>(NaGet.Env.PackageListFile);\r
61                         } catch (FileNotFoundException) {\r
62                                 availablePkgList = new PackageList<Package>();\r
63                         }\r
64                         \r
65                         try {\r
66                                 installedPkgList = NaGet.Utils.GetDeserializedObject<PackageList<InstalledPackage>>(NaGet.Env.ArchiveInstalledPackageListFile);\r
67                         } catch (FileNotFoundException) {\r
68                                 installedPkgList = new PackageList<InstalledPackage>();\r
69                         }\r
70                         \r
71                         try {\r
72                                 systemInstalledPkgList = NaGet.Utils.GetDeserializedObject<PackageList<InstalledPackage>>(NaGet.Env.SystemInstalledPackageListFile);\r
73                         } catch (FileNotFoundException) {\r
74                                 systemInstalledPkgList = new PackageList<InstalledPackage>();\r
75                         }\r
76                         \r
77                         \r
78                         systemInstalledLogList = new List<InstallationLog>();\r
79                         try {\r
80                                 systemInstalledLogList.AddRange(\r
81                                         NaGet.Utils.GetDeserializedObject<InstallationLog[]>(NaGet.Env.SystemInstalledPackageLogFile)\r
82                                 );\r
83                         } catch (Exception) {\r
84                                 // do nothing\r
85                         }\r
86                 }\r
87                 \r
88                 /// <summary>\r
89                 /// ファイルリストから読み込まれたパッケージのリスト\r
90                 /// をファイルに書き込む。\r
91                 /// </summary>\r
92                 public void SaveAvailablePackageList()\r
93                 {\r
94                         NaGet.Utils.PutSerializeObject(NaGet.Env.PackageListFile, availablePkgList);\r
95                 }\r
96                 /// <summary>\r
97                 /// 本ソフトウェアを介してインストールされたパッケージのリスト\r
98                 /// をファイルに書き込む。\r
99                 /// </summary>\r
100                 public void SaveInstalledPackageList()\r
101                 {\r
102                         NaGet.Utils.PutSerializeObject(NaGet.Env.ArchiveInstalledPackageListFile, installedPkgList);\r
103                 }\r
104                 /// <summary>\r
105                 /// システムから検出されたパッケージのリスト\r
106                 /// をファイルに書き込む。\r
107                 /// </summary>\r
108                 public void SaveSystemInstalledPackageList()\r
109                 {\r
110                         NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageListFile, systemInstalledPkgList);\r
111                 }\r
112                 /// <summary>\r
113                 /// インストールログ\r
114                 /// をファイルに書き込む。\r
115                 /// </summary>\r
116                 public void SaveSystemInstalledLogList()\r
117                 {\r
118                         NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageLogFile, systemInstalledLogList);\r
119                 }\r
120                 \r
121                 /// <summary>\r
122                 /// 本オブジェクトの保有しているパッケージ情報の全てをファイルに書き出す。\r
123                 /// </summary>\r
124                 public void CommitToFile()\r
125                 {\r
126                         SaveAvailablePackageList();\r
127                         SaveInstalledPackageList();\r
128                         SaveSystemInstalledPackageList();\r
129                         \r
130                         SaveSystemInstalledLogList();\r
131                 }\r
132                 \r
133                 #endregion\r
134                 \r
135                 #region パッケージインストール検知関連\r
136                 \r
137                 /// <summary>\r
138                 /// 本ソフトウェアを介してインストールされたパッケージを検出する。\r
139                 /// 具体的には<see cref="NaGet.Env.ArchiveProgramFiles" />\r
140                 /// で指定されたフォルダの下を見る。\r
141                 /// </summary>\r
142                 public void DetectInstalledPkgs()\r
143                 {\r
144                         PackageList<InstalledPackage> pkgList = new PackageList<InstalledPackage>();\r
145                         if (Directory.Exists(NaGet.Env.ArchiveProgramFiles)) {\r
146                                 foreach (string path in NaGet.Utils.ExtendWildcardFile(NaGet.Env.ArchiveProgramFiles, Path.Combine("*", ".applistation.package.xml"))) {\r
147                                         pkgList.AddPackage(NaGet.Utils.GetDeserializedObject<InstalledPackage>(path));\r
148                                 }\r
149                                 this.installedPkgList = pkgList;\r
150                         }\r
151                 }\r
152                 \r
153                 /// <summary>\r
154                 /// レジストリから、コンピュータにインストールされたパッケージを検出し、\r
155                 /// インストールトリストに登録(更新)をする。このとき、\r
156                 /// インストールのログを見て可能な限りパッケージ情報を補完する。\r
157                 /// </summary>\r
158                 public void DetectSystemInstalledPkgs()\r
159                 {\r
160                         List<InstalledPackage> installedPkgList = new List<InstalledPackage>();\r
161                         installedPkgList.AddRange(RegistriedUninstallers.DetectInstalledPackages(availablePkgList));\r
162                         \r
163                         // インストールのログを見て可能な限りパッケージ情報を補完する。\r
164                         for (int i = 0; i < installedPkgList.Count; i++) {\r
165                                 InstalledPackage pkg = installedPkgList[i];                             \r
166                                 int count = installedPkgList.FindAll(PackageList<InstalledPackage>.GetPredicateForPackageName(pkg.Name)).Count;\r
167 \r
168                                 foreach (InstallationLog log in systemInstalledLogList.FindAll(createPackageNamePredicator(pkg))) {\r
169                                         // 1. バージョンがアンインストール情報から取得できなかったときは無条件で登録\r
170                                         // 2. 同一名パッケージがない場合は無条件で登録\r
171                                         // 3. 複数個同一パッケージがインストールされている場合は、バージョン比較して登録。\r
172                                         if (string.IsNullOrEmpty(pkg.Version) ||\r
173                                             count < 2 ||\r
174                                             log.Package.Version == pkg.Version) {\r
175                                                 \r
176                                                 // 補完したパッケージ情報への差し替え\r
177                                                 UninstallInformation pkgUninstInfo = pkg.UninstallInfo;\r
178                                                 NaGet.Utils.FieldCopy((Package) log.Package, ref pkg);\r
179                                                 pkg.UninstallInfo = pkgUninstInfo;\r
180                                                 if (pkg.UninstallInfo.InstallDate == null) { // インストール日時の補完\r
181                                                         pkg.UninstallInfo.InstallDate = log.Date;\r
182                                                 }\r
183                                                 \r
184                                                 break;\r
185                                         }\r
186                                 }\r
187                         }\r
188                         this.systemInstalledPkgList.Packages = installedPkgList.ToArray();\r
189                 }\r
190                 \r
191                 #endregion\r
192                 \r
193                 #region パッケージ便利メソッド\r
194                 \r
195                 /// <summary>\r
196                 /// 全て(すなわち、本ソフトウェアを介してインストールされたものと、\r
197                 /// システムにインストールされたもの)のインストールされたパッケージを返す便利メソッド\r
198                 /// </summary>\r
199                 /// <returns>全てのインストールされたパッケージのイテレータ</returns>\r
200                 public IEnumerable<InstalledPackage> GetAllInstalledPackages()\r
201                 {\r
202                         return NaGet.Utils.MeargeEnumerable<InstalledPackage>(\r
203                                 installedPkgList.GetEnumerator(),\r
204                                 systemInstalledPkgList.GetEnumerator()\r
205                         );\r
206                 }\r
207                 \r
208                 /// <summary>\r
209                 /// 全てのパッケージをイテレータで返す便利メソッド。\r
210                 /// </summary>\r
211                 /// <returns>パッケージのイテレータ</returns>\r
212                 public IEnumerable<Package> GetAllPackages()\r
213                 {\r
214                         return NaGet.Utils.MeargeEnumerable<Package>(\r
215                                 availablePkgList.GetEnumerator(),\r
216                                 (IEnumerator<Package>) GetAllInstalledPackages().GetEnumerator()\r
217                         );\r
218                 }\r
219                 \r
220                 /// <summary>\r
221                 /// 与えられたパッケージ参照エントリに対応するパッケージはインストール済みか否かを返す\r
222                 /// </summary>\r
223                 /// <seealso cref="PackageList.GetPackageForEntry(Entry)" />\r
224                 /// <param name="entry">パッケージ参照エントリ</param>\r
225                 /// <returns>対応するパッケージがインストール済みならば<code>true</code></returns>\r
226                 public bool IsInstalledFor(Entry entry)\r
227                 {\r
228                         return (installedPkgList.GetPackageForEntry(entry) != null) ||\r
229                                 (systemInstalledPkgList.GetPackageForEntry(entry) != null);\r
230                 }\r
231                 \r
232                 #endregion\r
233                 \r
234                 #region インストールログ関連\r
235                 \r
236                 /// <summary>\r
237                 /// 指定パッケージ名に対応するログを判定するPredicate\r
238                 /// </summary>\r
239                 /// <param name="pkg">判定する指定パッケージ</param>\r
240                 /// <returns>Predicate</returns>\r
241                 private Predicate<InstallationLog> createPackageNamePredicator(Package pkg)\r
242                 {\r
243                         return delegate(InstallationLog log) {\r
244                                 return log.Package.Name == pkg.Name;\r
245                         };\r
246                 }\r
247                 \r
248                 /// <summary>\r
249                 /// インストールログにインストール情報を追加する。\r
250                 /// ファイルへの書き込みは行われない。\r
251                 /// </summary>\r
252                 /// <remarks>過去の同一パッケージ名のログは消去される</remarks>\r
253                 /// <param name="inst">書き込むインストール情報</param>\r
254                 public void WriteInstallationLog(Installation inst)\r
255                 {\r
256                         // 重複は削除\r
257                         systemInstalledLogList.RemoveAll(createPackageNamePredicator(inst.InstalledPackage));\r
258                         \r
259                         InstallationLog newLog = new InstallationLog();\r
260                         newLog.Date = DateTime.Now;\r
261                         newLog.Package = inst.InstalledPackage;\r
262                         \r
263                         systemInstalledLogList.Add(newLog);\r
264                 }\r
265                 \r
266                 #endregion\r
267         }\r
268 }\r