• R/O
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javaandroidc++linuxc#objective-ccocoa誰得qtrubybathyscaphegamephpguicwindows翻訳pythonomegattwitterframeworkbtronarduinovb.net計画中(planning stage)directxpreviewertestゲームエンジンdom

FreeTrainの進化系を目指す


Commit MetaInfo

Revision72 (tree)
Zeit2017-05-08 00:05:00
Autorc477

Log Message

[DDD]文字列型IDを専用クラス化

Ändern Zusammenfassung

Diff

--- trunk/TestCoreProject/core/RepositoryBaseTest.cs (revision 71)
+++ trunk/TestCoreProject/core/RepositoryBaseTest.cs (revision 72)
@@ -6,6 +6,7 @@
66 using static Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
77 using System.Collections.Generic;
88 using System.Linq;
9+using nft.framework;
910
1011 namespace TestCoreProject.core
1112 {
@@ -23,14 +24,14 @@
2324
2425 AreEqual(repository.Count, 0, "最初はCount=0");
2526
26- string id0 = "999";
27+ TestId id0 = new TestId("999");
2728 TestData data0 = new TestData(id0, $"#{id0}");
2829
2930 repository.Add(data0);
3031 AreEqual(repository.Count, 1, "追加したのでCount=1");
3132 AreEqual(repository[id0], data0, "ID=999で登録したオブジェクトが取得できること");
32- AreEqual(repository["000"], null, "存在しないID=000でnullが取得できること");
33- AreEqual(repository.RemoveByID("000"), null, "存在しないID=000で削除してもエラーにならずnullが返却されること");
33+ AreEqual(repository[new TestId("000")], null, "存在しないID=000でnullが取得できること");
34+ AreEqual(repository.RemoveByID(new TestId("000")), null, "存在しないID=000で削除してもエラーにならずnullが返却されること");
3435
3536 List<IHasNameAndID> list = repository.List.ToList<IHasNameAndID>();
3637 CollectionAssert.AreEqual(list, new List<IHasNameAndID> { data0 });
@@ -40,11 +41,11 @@
4041 AreEqual(removed, data0, "ID=999で登録したオブジェクトが削除されていること");
4142
4243 WriteLine("複数要素追加のテスト");
43- Dictionary<string, IHasNameAndID> savedData = new Dictionary<string, IHasNameAndID>();
44+ Dictionary<TestId, IHasNameAndID> savedData = new Dictionary<TestId, IHasNameAndID>();
4445 TestData data;
4546 for (int i = 1; i < 10; i++)
4647 { // 1~9まで追加していき、数とリストの中身が正しいことを確認
47- string id = $"{i}";
48+ TestId id = new TestId($"{i}");
4849 data = new TestData(id, $"#{id}");
4950 savedData.Add(id, data);
5051 repository.Add(data);
@@ -53,7 +54,7 @@
5354 }
5455 for (int i = 1; i < 10; i++)
5556 { // 一部のデータを削除しつつ、idとの紐付けが正しいことを確認
56- string id = $"{i}";
57+ TestId id = new TestId($"{i}");
5758 switch (i % 3)
5859 { // 3パターンを試す
5960 case 0: // 何もせず比較
@@ -80,21 +81,21 @@
8081 {
8182 this.repository = new TestRepository();
8283 WriteLine("IModelRepository拡張メソッドのテスト");
83- Dictionary<string, TestData> savedData = new Dictionary<string, TestData>();
84+ Dictionary<TestId, TestData> savedData = new Dictionary<TestId, TestData>();
8485 TestData data;
8586 for (int i = 1; i < 10; i++)
8687 { // 1~9まで追加していき、数とリストの中身が正しいことを確認
87- string id = $"{i}";
88+ TestId id = new TestId($"{i}");
8889 data = new TestData(id, $"#{id}");
8990 savedData.Add(id, data);
9091 repository.Add(data);
9192 CollectionAssert.AreEqual(repository.List.ToList<IHasNameAndID>(), savedData.Values);
9293 }
93- TestData _default = new TestData("default", "default");
94+ TestData _default = new TestData(new TestId("default"), "default");
9495 // 拡張メソッド findByID, hasID, removeByID
9596 for (int i = 1; i < 10; i++)
9697 { // 一部のデータを削除しつつ、idとの紐付けが正しいことを確認
97- string id = $"{i}";
98+ TestId id = new TestId($"{i}");
9899 switch (i % 3)
99100 {
100101 case 0: // 何もせず比較
@@ -111,13 +112,18 @@
111112 }
112113 }
113114
115+ class TestId : VAbstractIdentifier
116+ {
117+ public TestId(string idStr) : base(idStr) {}
118+ }
119+
114120 class TestData : IHasNameAndID
115121 {
116- private readonly string id;
122+ private readonly TestId id;
117123 private readonly string name;
118- public string ID { get { return id; } }
124+ public IIdentifier ID { get { return id; } }
119125 public string Name { get { return name; } }
120- public TestData(string id, string name)
126+ public TestData(TestId id, string name)
121127 {
122128 this.id = id;
123129 this.name = name;
@@ -124,7 +130,7 @@
124130 }
125131 }
126132
127- class TestRepository : RepositoryBase<TestData>
133+ class TestRepository : RepositoryBase<TestId,TestData>
128134 {
129135
130136 }
--- trunk/core/core/ApparentAssignor.cs (revision 71)
+++ trunk/core/core/ApparentAssignor.cs (revision 72)
@@ -20,10 +20,10 @@
2020 /// This class can be used as a base class of custom assignor.
2121 /// </summary>
2222 public class DefaultApparentAssignor : IApparentAssignor {
23- static readonly string CID_DefGround = "system\\BareLandTexture";
24- static readonly string CID_DefCliff = "system\\DefaultCliffTexture";
25- static readonly string CID_UnderWater = "system\\UnderWaterTexture";
26- static readonly string CID_UnderWaterCliff = "system\\UnderWaterCliffTexture";
23+ static readonly VContributionId CID_DefGround = new VContributionId(VPluginId.System, "BareLandTexture");
24+ static readonly VContributionId CID_DefCliff = new VContributionId(VPluginId.System, "DefaultCliffTexture");
25+ static readonly VContributionId CID_UnderWater = new VContributionId(VPluginId.System, "UnderWaterTexture");
26+ static readonly VContributionId CID_UnderWaterCliff = new VContributionId(VPluginId.System, "UnderWaterCliffTexture");
2727
2828 static public readonly DefaultApparentAssignor TheInstance = new DefaultApparentAssignor();
2929 protected IGroundPlateSet defaultGroundSet;
--- trunk/core/core/VWorldId.cs (nonexistent)
+++ trunk/core/core/VWorldId.cs (revision 72)
@@ -0,0 +1,30 @@
1+using nft.framework;
2+using System;
3+using System.Collections.Generic;
4+using System.Linq;
5+using System.Text;
6+using System.Threading.Tasks;
7+
8+namespace nft.core
9+{
10+ public class VWorldId : VAbstractIdentifier
11+ {
12+ public static readonly string PREFIX = "World:";
13+
14+ internal static VWorldId Generate()
15+ {
16+ return new VWorldId(PREFIX + DateTime.Now.Ticks);
17+ }
18+
19+ private VWorldId(string idStr) : base(idStr) {}
20+
21+ public string ShortID
22+ {
23+ get
24+ {
25+ long tick = long.Parse(this.AsString.Substring(PREFIX.Length));
26+ return $"{tick:X}";
27+ }
28+ }
29+ }
30+}
--- trunk/core/core/World.cs (revision 71)
+++ trunk/core/core/World.cs (revision 72)
@@ -16,9 +16,12 @@
1616 [Serializable]
1717 public class World : IHasNameAndID, IEnumerable
1818 {
19- public World(Size size, int districtUnitSize)
19+ private VWorldId id;
20+
21+ public World(Size size, int districtUnitSize)
2022 {
21- if( districtUnitSize<=0 )
23+ this.id = VWorldId.Generate();
24+ if ( districtUnitSize<=0 )
2225 throw new ArgumentException("Wrong size paramater","districtUnitSize");
2326 if( size.Width<=0 || size.Height<=0 )
2427 throw new ArgumentException("Wrong size paramater","size");
@@ -37,16 +40,11 @@
3740
3841 #region IHasNameAndID メンバ
3942
40- public string ID
43+ public IIdentifier ID
4144 {
42- get { return "World:"+ShortID; }
45+ get { return id; }
4346 }
4447
45- internal string ShortID
46- {
47- get { return string.Format("{0:X}", this.GetHashCode()); }
48- }
49-
5048 public string Name
5149 {
5250 get { return name; }
--- trunk/core/core/game/IGameMode.cs (revision 71)
+++ trunk/core/core/game/IGameMode.cs (revision 72)
@@ -120,7 +120,7 @@
120120
121121 #region IHasNameAndID メンバ
122122
123- public string ID {
123+ public IIdentifier ID {
124124 get { throw new NotImplementedException(); }
125125 }
126126
--- trunk/core/core/game/MapGeneService.cs (revision 71)
+++ trunk/core/core/game/MapGeneService.cs (revision 72)
@@ -47,8 +47,9 @@
4747 public IWorldDivider DefaultWorldDividor
4848 {
4949 get
50- {
51- CtbWorldDivider dv = PluginManager.theInstance.GetContribution(@"system\SimpleDivider") as CtbWorldDivider;
50+ {
51+ VContributionId idDefault = new VContributionId(VPluginId.System, "SimpleDivider");
52+ CtbWorldDivider dv = PluginManager.theInstance.GetContribution(idDefault) as CtbWorldDivider;
5253 if(dv!=null)
5354 return dv.Divider;
5455 else
--- trunk/core/core/structure/Lot.cs (revision 71)
+++ trunk/core/core/structure/Lot.cs (revision 72)
@@ -1,5 +1,6 @@
11 using System;
22 using nft.core.geometry;
3+using nft.framework;
34
45 namespace nft.core.structure
56 {
@@ -21,7 +22,7 @@
2122 Bounds = new Rect3D(loc,structure.Size);
2223 }
2324
24- public readonly string ID;
25+ public readonly IIdentifier ID;
2526 public readonly object Category;
2627 public readonly int Level;
2728 public readonly Rect3D Bounds;
--- trunk/core/debug/TestXnaForm.cs (revision 71)
+++ trunk/core/debug/TestXnaForm.cs (revision 72)
@@ -30,10 +30,10 @@
3030 List<I3DObject> structures = new List<I3DObject>();
3131 protected override void OnLoad(EventArgs e)
3232 {
33- CtbImageResource ir1 = PluginManager.theInstance.GetContribution(@"test\tex112x136x96") as CtbImageResource;
34- CtbImageResource ir2 = PluginManager.theInstance.GetContribution(@"test\tex32x48x56") as CtbImageResource;
35- ITexture tx1 = GM.CreateStaticTexture(ResourceKey.CreateKey(ir1, ir2.ID), ir1.Data.Default.ImageSrc);
36- ITexture tx2 = GM.CreateStaticTexture(ResourceKey.CreateKey(ir2, ir2.ID), ir2.Data.Default.ImageSrc);
33+ CtbImageResource ir1 = PluginManager.theInstance.GetContribution(new VContributionId(@"test\tex112x136x96")) as CtbImageResource;
34+ CtbImageResource ir2 = PluginManager.theInstance.GetContribution(new VContributionId(@"test\tex32x48x56")) as CtbImageResource;
35+ ITexture tx1 = GM.CreateStaticTexture(ResourceKey.CreateKey(ir1, ir2.ID.AsString), ir1.Data.Default.ImageSrc);
36+ ITexture tx2 = GM.CreateStaticTexture(ResourceKey.CreateKey(ir2, ir2.ID.AsString), ir2.Data.Default.ImageSrc);
3737 ICubicStructure st1 = GM.CreateStructure(0, null, tx1, new Point3D(112, 96, 136));
3838 ICubicStructure st2 = GM.CreateStructure(0, null, tx2, new Point3D(32, 56, 48));
3939 st1.Location = new PointF3D(40f, -20f, -40f);
--- trunk/core/impl/game/District.cs (revision 71)
+++ trunk/core/impl/game/District.cs (revision 72)
@@ -13,24 +13,22 @@
1313 /// </summary>
1414 public class District : IDistrict
1515 {
16- public District(World w, ITerrainMap map, Rectangle area )
16+ private VDistrictId id;
17+
18+ public District(World w, ITerrainMap map, Rectangle area )
1719 {
18- world = w;
20+ world = w;
1921 worldPos = area.Location;
20- int us = world.UnitSize;
22+ this.id = VDistrictId.Generate(world, worldPos);
23+ int us = world.UnitSize;
2124 mapSize = new Size(area.Width*us,area.Height*us);
2225 }
2326
2427 #region IHasNameAndID メンバ
25- public string ID
28+ public IIdentifier ID
2629 {
27- get { return string.Format("District:{0}-{1:00}{2:00}-{3}", world.ShortID, worldPos.X, worldPos.Y, ShortID); }
30+ get { return id; }
2831 }
29- protected readonly string id;
30- public string ShortID
31- {
32- get { return string.Format("{0:X}", this.GetHashCode()); }
33- }
3432
3533 public string Name
3634 {
--- trunk/core/impl/game/VDistrictId.cs (nonexistent)
+++ trunk/core/impl/game/VDistrictId.cs (revision 72)
@@ -0,0 +1,35 @@
1+using nft.core;
2+using nft.framework;
3+using System;
4+using System.Collections.Generic;
5+using System.Drawing;
6+using System.Linq;
7+using System.Text;
8+using System.Threading.Tasks;
9+
10+namespace nft.impl.game
11+{
12+ public class VDistrictId : VAbstractIdentifier
13+ {
14+
15+ public static readonly string PREFIX = "District:";
16+
17+ internal static VDistrictId Generate(World w, Point pos)
18+ {
19+ string idStr = $"District:{((VWorldId)w.ID).ShortID}-{pos.X:00}{pos.Y:00}-{DateTime.Now.Ticks}";
20+ return new VDistrictId(idStr);
21+ }
22+
23+ private VDistrictId(string idStr) : base(idStr) { }
24+
25+ public string ShortID
26+ {
27+ get
28+ {
29+ int n = this.AsString.LastIndexOf("-");
30+ long tick = long.Parse(this.AsString.Substring(n + 1));
31+ return $"{tick:X}";
32+ }
33+ }
34+ }
35+}
--- trunk/core/impl/view/ViewCommands.cs (revision 71)
+++ trunk/core/impl/view/ViewCommands.cs (revision 72)
@@ -10,23 +10,24 @@
1010 using Geocon = nft.core.geometry.GeometricConstants;
1111 using System.Drawing;
1212 using nft.core.view;
13+using nft.framework.plugin;
1314
1415 namespace nft.impl.view {
1516 public class ViewCommands {
1617
17- public static ICommandProcedure GetRotateRightCommand(String id){
18+ public static ICommandProcedure GetRotateRightCommand(VContributionId id){
1819 return new ViewRotaterR();
1920 }
2021
21- public static ICommandProcedure GetRotateLeftCommand(String id) {
22+ public static ICommandProcedure GetRotateLeftCommand(VContributionId id) {
2223 return new ViewRotaterL();
2324 }
2425
25- public static ICommandProcedure GetZoomInCommand(String id) {
26+ public static ICommandProcedure GetZoomInCommand(VContributionId id) {
2627 return new ZoomInCommand();
2728 }
2829
29- public static ICommandProcedure GetZoomOutCommand(String id) {
30+ public static ICommandProcedure GetZoomOutCommand(VContributionId id) {
3031 return new ZoomOutCommand();
3132 }
3233
--- trunk/framework/contributions/ui/CtbCommandUI.cs (revision 71)
+++ trunk/framework/contributions/ui/CtbCommandUI.cs (revision 72)
@@ -43,7 +43,7 @@
4343
4444 protected void ConfirmIDAttribute(ParamsReader e) {
4545 if (e["id"].IsNull) {
46- e.OverWrite("id", this.id);
46+ e.OverWrite("id", this.id.AsString);
4747 }
4848 }
4949 }
--- trunk/framework/framework/Directories.cs (revision 71)
+++ trunk/framework/framework/Directories.cs (revision 72)
@@ -248,9 +248,8 @@
248248 Contribution c = o as Contribution;
249249 if (c != null)
250250 {
251- string pid = c.Parent.ID;
252- string cid = c.ID.Substring(pid.Length + Contribution.PID_Sepalator.Length);
253- return subdir_plugins + Path.Combine(pid, cid);
251+ VContributionId cid = c.ContributionID;
252+ return subdir_plugins + Path.Combine(cid.PluginID, cid.SubID);
254253 }
255254 else
256255 {
--- trunk/framework/framework/IHasNameAndID.cs (revision 71)
+++ trunk/framework/framework/IHasNameAndID.cs (revision 72)
@@ -7,7 +7,27 @@
77 /// </summary>
88 public interface IHasNameAndID
99 {
10- string ID {get;}
10+ IIdentifier ID {get;}
1111 string Name {get;}
1212 }
13+
14+ public static class IHasNameAndIDExtension
15+ {
16+ public static bool Equals(this IHasNameAndID me, object target)
17+ {
18+ IHasNameAndID another = target as IHasNameAndID;
19+ if (another == null) return false;
20+ return me.ID.Equals(another.ID) && me.GetType().Equals(another.GetType());
21+ }
22+
23+ public static int GetHashCode(this IHasNameAndID me)
24+ {
25+ return me.ID.GetHashCode();
26+ }
27+
28+ public static string ToString(this IHasNameAndID me)
29+ {
30+ return String.Format("{0}#{1}'{2}'", me.GetType().Name, me.ID.AsString, me.Name);
31+ }
32+ }
1333 }
--- trunk/framework/framework/IIdentifier.cs (nonexistent)
+++ trunk/framework/framework/IIdentifier.cs (revision 72)
@@ -0,0 +1,13 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Linq;
4+using System.Text;
5+using System.Threading.Tasks;
6+
7+namespace nft.framework
8+{
9+ public interface IIdentifier
10+ {
11+ string AsString { get; }
12+ }
13+}
--- trunk/framework/framework/VAbstractIdentifier.cs (nonexistent)
+++ trunk/framework/framework/VAbstractIdentifier.cs (revision 72)
@@ -0,0 +1,43 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Diagnostics;
4+using System.IO;
5+using System.Linq;
6+using System.Text;
7+using System.Threading.Tasks;
8+
9+namespace nft.framework
10+{
11+ [Serializable]
12+ public abstract class VAbstractIdentifier : IIdentifier
13+ {
14+ protected readonly string _idstr;
15+
16+ protected VAbstractIdentifier(string IdStr)
17+ {
18+ this._idstr = IdStr;
19+ }
20+
21+ public override bool Equals(object target)
22+ {
23+ VAbstractIdentifier another = target as VAbstractIdentifier;
24+ if (another == null) return false;
25+ return this._idstr.Equals(another._idstr) && this.GetType().Equals(another.GetType());
26+ }
27+
28+ public override int GetHashCode()
29+ {
30+ return this._idstr.GetHashCode();
31+ }
32+
33+ public override string ToString()
34+ {
35+ return String.Format("{0}'{1}'", this.GetType().Name, this.AsString);
36+ }
37+
38+ public string AsString
39+ {
40+ get { return _idstr; }
41+ }
42+ }
43+}
--- trunk/framework/framework/drawing/ResourceKey.cs (revision 71)
+++ trunk/framework/framework/drawing/ResourceKey.cs (revision 72)
@@ -47,19 +47,19 @@
4747 }
4848
4949 public static ResourceKey CreateKey(Contribution c, UInt16 local_id) {
50- return new ResourceKey(c.ID, local_id.ToString("X4"));
50+ return new ResourceKey(c.ID.AsString, local_id.ToString("X4"));
5151 }
5252
5353 public static ResourceKey CreateKey(Contribution c, UInt32 local_id) {
54- return new ResourceKey(c.ID, local_id.ToString("X8"));
54+ return new ResourceKey(c.ID.AsString, local_id.ToString("X8"));
5555 }
5656
5757 public static ResourceKey CreateKey(Contribution c, String local_id) {
58- return new ResourceKey(c.ID, local_id);
58+ return new ResourceKey(c.ID.AsString, local_id);
5959 }
6060
6161 public static ResourceKey CreateKey(Plugin p, String local_id) {
62- return new ResourceKey(p.ID, local_id);
62+ return new ResourceKey(p.ID.AsString, local_id);
6363 }
6464
6565 public override bool Equals(object obj) {
--- trunk/framework/framework/plugin/Contribution.cs (revision 71)
+++ trunk/framework/framework/plugin/Contribution.cs (revision 72)
@@ -20,33 +20,9 @@
2020 [Serializable]
2121 public abstract class Contribution : ISerializable, IHasNameAndID, IAddable
2222 {
23- #region Contribution ID generation
24- // Contribution ID will be used as a part of filepath.
25- // {Plugin_id}\{Contribution_short_id}
26- static public readonly string PID_Sepalator = "\\";
27- static string GenerateID( ParamsReader contrib )
28- {
29- string short_id = contrib["id"].InnerText;
30- if( short_id == null )
31- {
32- string templ = I18n.T("An attribute '{1}' is required for the node '{0}'.");
33- throw new PluginXmlException(contrib,string.Format(
34- templ,"contribution","name",contrib.SourceURI));
35- }
36-
37- string pname = PluginUtil.GetPluginDirName(contrib);
38- return pname + PID_Sepalator + short_id;
39- }
40- static string GenerateID(Plugin owner, string short_id)
41- {
42- string pname = owner.ID;
43- return pname + PID_Sepalator + short_id;
44- }
45- #endregion
46-
4723 protected Contribution(Plugin owner, ParamsReader contrib)
4824 {
49- this.id = GenerateID(contrib);
25+ this.id = VContributionId.CreateFrom(contrib);
5026 this.parent = owner;
5127 this.CtbType = ParseType(contrib);
5228 //Debug.WriteLine("name:" + name + " ,baseDir:" + baseDir);
@@ -55,7 +31,7 @@
5531 }
5632
5733 protected Contribution(Plugin owner, ParamsReader contrib, string name, string description) {
58- this.id = GenerateID(contrib);
34+ this.id = VContributionId.CreateFrom(contrib);
5935 this.parent = owner;
6036 this.CtbType = ParseType(contrib);
6137 this.name = name;
@@ -68,7 +44,7 @@
6844 {
6945 this.parent = owner;
7046 this.CtbType = _type;
71- this.id = GenerateID(owner, short_id);
47+ this.id = new VContributionId(owner, short_id);
7248 this.name = _name;
7349 this.description = _description;
7450 }
@@ -187,7 +163,7 @@
187163 /// Either GUID or URI, but can be anything as long
188164 /// as it's unique.
189165 /// </summary>
190- protected readonly string id;
166+ protected readonly VContributionId id;
191167 /// <summary>
192168 /// Name of this contribution.
193169 /// </summary>
@@ -244,15 +220,7 @@
244220 }
245221
246222 protected Contribution GetOtherContribution(string pathorid) {
247- string id;
248- int n = pathorid.IndexOf(PID_Sepalator);
249- if (n == -1) {
250- id = GenerateID(parent, pathorid);
251- } else if(n==1 && pathorid[0]=='.'){
252- id = GenerateID(parent, pathorid.Substring(2));
253- } else{
254- id = pathorid;
255- }
223+ VContributionId id = VContributionId.CreateUsingOrigin(pathorid, this.Parent);
256224 return PluginManager.theInstance.GetContribution(id);
257225 }
258226
@@ -301,7 +269,7 @@
301269
302270 [Serializable]
303271 internal sealed class ReferenceImpl : IObjectReference {
304- private string id=null;
272+ private VContributionId id=null;
305273 public object GetRealObject(StreamingContext context) {
306274 object o = PluginManager.theInstance.GetContribution(id);
307275 if(o==null)
@@ -310,12 +278,13 @@
310278 return o;
311279 }
312280 }
281+
313282 #region IHasNameAndID メンバ
314283 /// <summary>
315284 /// Contribution ID can be used as a part of file path.
316285 /// '{Plugin_id}\{Contribution_short_id}'
317286 /// </summary>
318- public string ID
287+ public IIdentifier ID
319288 {
320289 get
321290 {
@@ -333,5 +302,9 @@
333302
334303 #endregion
335304
305+ public VContributionId ContributionID
306+ {
307+ get { return id; }
308+ }
336309 }
337310 }
--- trunk/framework/framework/plugin/Plugin.cs (revision 71)
+++ trunk/framework/framework/plugin/Plugin.cs (revision 72)
@@ -14,9 +14,9 @@
1414 public const string PluginFileName = "plugin.xml";
1515 #region IHasNameAndID メンバ
1616
17- private string _id;
17+ private VPluginId _id;
1818 // plugin 'id' is equals to the subdir name where "plugin.xml" is placed.
19- public string ID {
19+ public IIdentifier ID {
2020 get { return _id; }
2121 }
2222
@@ -23,9 +23,13 @@
2323 public string Name {
2424 get { return _title; }
2525 }
26-
2726 #endregion
2827
28+ public VPluginId PluginID
29+ {
30+ get { return _id; }
31+ }
32+
2933 private string _title;
3034 public string Title { get { return _title; } }
3135
@@ -127,8 +131,8 @@
127131 /// <param name="path">URI indicates file source path. folder name is used as plugin ID.</param>
128132 public Plugin(Uri path, DateTime lastModified) {
129133 this.Uri = path;
134+ _id = new VPluginId(path);
130135 _lastModified = lastModified;
131- _id = Path.GetFileName(path.LocalPath.Replace("/", "\\"));
132136 }
133137
134138 internal protected void LoadParams(ParamsReader reader){
--- trunk/framework/framework/plugin/PluginManager.cs (revision 71)
+++ trunk/framework/framework/plugin/PluginManager.cs (revision 72)
@@ -32,7 +32,7 @@
3232 /// <summary>
3333 /// Plugins keyed by their names.
3434 /// </summary>
35- private readonly Dictionary<string, Plugin> pluginMap = new Dictionary<string, Plugin>();
35+ private readonly Dictionary<VPluginId, Plugin> pluginMap = new Dictionary<VPluginId, Plugin>();
3636
3737 /// <summary>
3838 /// Contribution factories that are used to load contributions.
@@ -42,7 +42,7 @@
4242 /// <summary>
4343 /// Contributions keyed by their IDs.
4444 /// </summary>
45- private readonly Dictionary<string, Contribution> contributionMap = new Dictionary<string, Contribution>();
45+ private readonly Dictionary<VContributionId, Contribution> contributionMap = new Dictionary<VContributionId, Contribution>();
4646
4747 /// <summary>
4848 /// Contribution Types keyed by their CtbTypes (string specified a Type of Contribution).
@@ -126,7 +126,7 @@
126126 ParamsReader reader = new ParamsReader(path, parser);
127127 pluginSet.Add( p );
128128 p.LoadParams(reader["plug-in"]);
129- if( pluginMap.ContainsKey(p.ID) )
129+ if( pluginMap.ContainsKey(p.PluginID) )
130130 {
131131 p._state = InstallationState.FatalError;
132132 // loaded more than once
@@ -133,9 +133,9 @@
133133 // maybe same subdir name in different plugin dirs.
134134 throw new Exception( string.Format(
135135 "プラグイン「{0}」は{1}と{2}の二箇所からロードされています",
136- p.ID, p.Uri, (pluginMap[p.ID]).Uri) );
136+ p.ID, p.Uri, (pluginMap[p.PluginID]).Uri) );
137137 }
138- pluginMap.Add( p.ID, p );
138+ pluginMap.Add( p.PluginID, p );
139139 }
140140 catch( Exception e )
141141 {
@@ -159,8 +159,8 @@
159159 int ptr=0;
160160
161161 // Add system default plugin to the order-list at first.
162- Plugin p = GetPlugin("system");
163- monitor.Progress(2, 1, p.ID);
162+ Plugin p = GetPlugin(VPluginId.System);
163+ monitor.Progress(2, 1, p.ID.AsString);
164164 plugins[ptr++] = p;
165165 pluginSet.Remove(p);
166166 // Loop until pluginSet becomes empty.
@@ -167,7 +167,7 @@
167167 while( pluginSet.Count>0 )
168168 {
169169 p = pluginSet[0];
170- monitor.Progress(2,1,p.ID);
170+ monitor.Progress(2,1,p.ID.AsString);
171171 try
172172 {
173173 Plugin pr;
@@ -211,7 +211,7 @@
211211
212212 foreach( Plugin p in plugins )
213213 {
214- monitor.Progress(2,1,p.ID);
214+ monitor.Progress(2,1,p.ID.AsString);
215215 try
216216 {
217217 LoadBinaries(p, p._reader);
@@ -226,7 +226,7 @@
226226
227227 foreach( Plugin p in plugins )
228228 {
229- monitor.Progress(2,1,p.ID);
229+ monitor.Progress(2,1,p.ID.AsString);
230230 try
231231 {
232232 // this will call AddContribution method
@@ -260,7 +260,7 @@
260260 } else {
261261 contrib.PrepareCacheData(false);
262262 contrib._state = InstallationState.Ready;
263- monitor.Progress(2, 1, contrib.ID);
263+ monitor.Progress(2, 1, contrib.ID.AsString);
264264 }
265265 } catch (Exception e) {
266266 contrib._state = InstallationState.FatalError;
@@ -280,7 +280,7 @@
280280 } else {
281281 contrib.PrepareCacheData(false);
282282 contrib._state = InstallationState.Ready;
283- monitor.Progress(2, 1, contrib.ID);
283+ monitor.Progress(2, 1, contrib.ID.AsString);
284284 }
285285 }
286286 catch( Exception e )
@@ -298,7 +298,7 @@
298298 h();
299299 contrib.PrepareCacheData(false);
300300 contrib._state = InstallationState.Ready;
301- monitor.Progress(2, 1, contrib.ID);
301+ monitor.Progress(2, 1, contrib.ID.AsString);
302302 } catch (Exception e) {
303303 contrib._state = InstallationState.FatalError;
304304 string msg = I18n.F("Failed to initialize contribution[{1}] in the plug-in:{0}.",
@@ -359,7 +359,7 @@
359359 List<Plugin> a = new List<Plugin>();
360360 foreach (ParamsReader depend in _reader.EnumChildren("depend")) {
361361 string name = depend["on"].InnerText;
362- Plugin p2 = GetPlugin(name);
362+ Plugin p2 = GetPlugin(new VPluginId(name));
363363 if (p2 == null) {
364364 string msg = I18n.F("Dependent plug-in:{1} (required for the plug-in:{0}) is not found.", p.ID, name);
365365 throw new Exception(msg);
@@ -581,18 +581,18 @@
581581 }
582582
583583 public void AddContribution( Contribution contrib ) {
584- if(contributionMap.ContainsKey(contrib.ID))
584+ if(contributionMap.ContainsKey(contrib.ContributionID))
585585 {
586586 // TODO:
587587 Debug.WriteLine("Duplicate contribution id found:"+contrib.ID);
588588 }
589- contributionMap.Add( contrib.ID, contrib );
589+ contributionMap.Add( contrib.ContributionID, contrib );
590590 }
591591
592592 /// <summary>
593593 /// Gets the contribution with a given ID, or null if not found.
594594 /// </summary>
595- public Contribution GetContribution( string id ) {
595+ public Contribution GetContribution( VContributionId id ) {
596596 Contribution ctb;
597597 if(contributionMap.TryGetValue(id, out ctb)){
598598 return ctb;
@@ -605,9 +605,9 @@
605605 /// <summary>
606606 /// Get the plug-in of the specified name, or null if not found.
607607 /// </summary>
608- public Plugin GetPlugin( string name )
608+ public Plugin GetPlugin( VPluginId id )
609609 {
610- return pluginMap[name];
610+ return pluginMap[id];
611611 }
612612
613613 public Type GetDefinedType( string ctbType )
@@ -626,7 +626,7 @@
626626 string output = "Installed Plugins (except for system plugins).";
627627 foreach(Plugin p in pluginMap.Values)
628628 {
629- if(!p.ID.StartsWith("system"))
629+ if(!p.ID.AsString.StartsWith("system"))
630630 {
631631 output+=Environment.NewLine;
632632 output+=string.Format("{0}[{1}] {2:yyyyMMdd-HHmm}",p.Title,p.ID,p.lastModifiedTime);
--- trunk/framework/framework/plugin/PluginUtil.cs (revision 71)
+++ trunk/framework/framework/plugin/PluginUtil.cs (revision 72)
@@ -8,6 +8,7 @@
88 using nft.util;
99 using nft.ui.command;
1010 using nft.framework.loader;
11+using System.Text.RegularExpressions;
1112
1213 namespace nft.framework.plugin
1314 {
@@ -17,12 +18,22 @@
1718 public class PluginUtil
1819 {
1920 private static Dictionary<string, Assembly> assemblies = new Dictionary<string,Assembly>();
20-
21+
2122 /// <summary>
22- /// Load a new Contribution by reading a type from the manifest XML element.
23- /// The "codeBase" attribute and the "name" attribute of
24- /// a class element are used to determine the class to be loaded.
25- /// </summary>
23+ /// Plugin, Contribution の IDとして適切な文字のみで構成されているかチェックするための正規表現
24+ /// </summary>
25+ public static readonly Regex IdCharValidator;
26+
27+ static PluginUtil()
28+ {
29+ IdCharValidator = new Regex(@"^[a-zA-Z0-9_\.\-]+$");
30+ }
31+
32+ /// <summary>
33+ /// Load a new Contribution by reading a type from the manifest XML element.
34+ /// The "codeBase" attribute and the "name" attribute of
35+ /// a class element are used to determine the class to be loaded.
36+ /// </summary>
2637 /// <param name="p">owner plugin</param>
2738 /// <param name="contrib">contribution target node</param>
2839 public static Contribution createContributionObject(Plugin p, ParamsReader elm) {
--- trunk/framework/framework/plugin/PluginXmlException.cs (revision 71)
+++ trunk/framework/framework/plugin/PluginXmlException.cs (revision 72)
@@ -41,7 +41,7 @@
4141 if (plugin != null) return true;
4242
4343 string pname = Path.GetFileName(Path.GetDirectoryName(node.SourceURI)+"");
44- plugin = PluginManager.theInstance.GetPlugin(pname);
44+ plugin = PluginManager.theInstance.GetPlugin(new VPluginId(pname));
4545 return plugin != null;
4646 }
4747
--- trunk/framework/framework/plugin/VContributionId.cs (nonexistent)
+++ trunk/framework/framework/plugin/VContributionId.cs (revision 72)
@@ -0,0 +1,97 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Diagnostics;
4+using System.Linq;
5+using System.Text;
6+using System.Threading.Tasks;
7+
8+namespace nft.framework.plugin
9+{
10+ [Serializable]
11+ public sealed class VContributionId : VAbstractIdentifier
12+ {
13+ // Contribution ID will be used as a part of filepath.
14+ // {Plugin_id}\{Contribution_short_id}
15+ static public readonly string PID_Sepalator = "\\";
16+
17+ internal static VContributionId CreateFrom(ParamsReader contribRootReader)
18+ {
19+ string short_id = contribRootReader["id"].InnerText;
20+ if (short_id == null)
21+ {
22+ string templ = I18n.T("An attribute '{1}' is required for the node '{0}'.");
23+ throw new PluginXmlException(contribRootReader, string.Format(
24+ templ, "contribution", "name", contribRootReader.SourceURI));
25+ }
26+
27+ string pname = PluginUtil.GetPluginDirName(contribRootReader);
28+ return new VContributionId(new VPluginId(pname), short_id);
29+ }
30+
31+ internal static VContributionId CreateUsingOrigin(string pathorid, Plugin origin)
32+ {
33+ int n = pathorid.IndexOf(PID_Sepalator);
34+ if (n == -1)
35+ {// 'hoge' -> { pluginID = origin.ID, subId = 'hoge' }
36+ return new VContributionId(origin, pathorid);
37+ }
38+ else if (n == 1 && pathorid[0] == '.')
39+ {// '.\hoge' -> { pluginID = origin.ID, subId = 'hoge' }
40+ return new VContributionId(origin, pathorid.Substring(2));
41+ }
42+ else
43+ {// 'fuga\hoge' -> { pluginID = 'fuga', subId = 'hoge' }
44+ return new VContributionId(pathorid.Substring(0, n), pathorid.Substring(n + PID_Sepalator.Length));
45+ }
46+ }
47+
48+ public VContributionId(Plugin owner, string subId) : this(owner.PluginID.AsString, subId)
49+ {}
50+
51+ public VContributionId(VPluginId pluginId, string subId) : this(pluginId.AsString, subId)
52+ {}
53+
54+ private VContributionId(string pluginId, string subId) : base(CombineWithValidating(pluginId, subId))
55+ {}
56+
57+ /// <summary>
58+ ///
59+ /// </summary>
60+ /// <param name="idStr"></param>
61+ [Obsolete("TODO:使わないようにしたい")]
62+ public VContributionId(string idStr) : base(idStr)
63+ {}
64+
65+ public string PluginID
66+ {
67+ get {
68+ int n = AsString.IndexOf(PID_Sepalator);
69+ return AsString.Substring(0, n);
70+ }
71+ }
72+
73+ public string SubID
74+ {
75+ get
76+ {
77+ int n = AsString.IndexOf(PID_Sepalator);
78+ return AsString.Substring(n + PID_Sepalator.Length);
79+ }
80+ }
81+
82+ private static string CombineWithValidating(string pluginId, string subId)
83+ {
84+ ValidateIdCaracters(pluginId, "Plugin-ID");
85+ ValidateIdCaracters(subId.Replace("factory#",""), "Sub-ID");
86+ return pluginId + PID_Sepalator + subId;
87+ }
88+
89+ private static void ValidateIdCaracters(string testStr, string argName)
90+ {
91+ string format = I18n.T("'{0}' contains invalid character(s) as a {1}.");
92+ Debug.Assert(
93+ PluginUtil.IdCharValidator.IsMatch(testStr), String.Format(format, testStr, argName)
94+ );
95+ }
96+ }
97+}
--- trunk/framework/framework/plugin/VPluginId.cs (nonexistent)
+++ trunk/framework/framework/plugin/VPluginId.cs (revision 72)
@@ -0,0 +1,32 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Diagnostics;
4+using System.IO;
5+using System.Linq;
6+using System.Text;
7+using System.Threading.Tasks;
8+
9+namespace nft.framework.plugin
10+{
11+ [Serializable]
12+ public sealed class VPluginId : VAbstractIdentifier
13+ {
14+ public static readonly VPluginId System = new VPluginId("system");
15+
16+ public VPluginId(Uri path) : this(Path.GetFileName(path.LocalPath.Replace("/", "\\")))
17+ {}
18+
19+ public VPluginId(string pluginId) : base(WithValidation(pluginId))
20+ {}
21+
22+
23+ private static string WithValidation(string testStr)
24+ {
25+ string format = I18n.T("'{0}' contains invalid character(s) as a {1}.");
26+ Debug.Assert(
27+ PluginUtil.IdCharValidator.IsMatch(testStr), String.Format(format, testStr, "Plugin-ID")
28+ );
29+ return testStr;
30+ }
31+ }
32+}
--- trunk/framework/framework/repository/DefaultRepositoryBuilder.cs (revision 71)
+++ trunk/framework/framework/repository/DefaultRepositoryBuilder.cs (revision 72)
@@ -8,16 +8,16 @@
88
99 namespace nft.framework.repository
1010 {
11- public class DefaultRepositoryBuilder<T,U> : IRepositoryBuilder<T> where T: class, IHasNameAndID where U: IRepository<T>
11+ public class DefaultRepositoryBuilder<S,T,U> : IRepositoryBuilder<S,T> where S: IIdentifier where T: class, IHasNameAndID where U: IRepository<S,T>
1212 {
13- protected Dictionary<string, T> dictionary = new Dictionary<string, T>();
13+ protected Dictionary<S, T> dictionary = new Dictionary<S, T>();
1414
1515 public void Add(T model)
1616 {
17- dictionary.Add(model.ID, model);
17+ dictionary.Add((S)model.ID, model);
1818 }
1919
20- public T RemoveByID(string id)
20+ public T RemoveByID(S id)
2121 {
2222 T ret;
2323 if (!dictionary.TryGetValue(id, out ret)) {
@@ -27,9 +27,9 @@
2727 return ret;
2828 }
2929
30- public IRepository<T> Finalize()
30+ public IRepository<S,T> Finalize()
3131 {
32- Type[] types = { typeof(IDictionary<string, T>) };
32+ Type[] types = { typeof(IDictionary<S, T>) };
3333 ConstructorInfo ci = typeof(U).GetConstructor(types);
3434 object[] args = { this.dictionary };
3535 U repository = (U) ci.Invoke( args );
--- trunk/framework/framework/repository/IRepository.cs (revision 71)
+++ trunk/framework/framework/repository/IRepository.cs (revision 72)
@@ -11,8 +11,9 @@
1111 /// データリポジトリのコアインターフェース
1212 /// 標準実装はRepositoryBase
1313 /// </summary>
14+ /// <typeparam name="S"></typeparam>
1415 /// <typeparam name="T"></typeparam>
15- public interface IRepository<T> where T: IHasNameAndID
16+ public interface IRepository<S,T> where T: IHasNameAndID where S: IIdentifier
1617 {
1718 /// <summary>
1819 /// モデルを追加する。既にモデル
@@ -25,7 +26,7 @@
2526 /// </summary>
2627 /// <param name="id"></param>
2728 /// <returns>removed model or null if not exist</returns>
28- T RemoveByID(string id);
29+ T RemoveByID(S id);
2930
3031 /// <summary>
3132 /// IDを指定してモデルを取得する。
@@ -33,7 +34,7 @@
3334 /// </summary>
3435 /// <param name="id"></param>
3536 /// <returns></returns>
36- T this[string id] { get; }
37+ T this[S id] { get; }
3738
3839 /// <summary>
3940 /// リポジトリに含まれるすべてのモデルのリストを取得します
@@ -54,12 +55,13 @@
5455 /// <summary>
5556 /// 指定したモデルを削除する。
5657 /// </summary>
58+ /// <typeparam name="S"></typeparam>
5759 /// <typeparam name="T"></typeparam>
5860 /// <param name="repository"></param>
5961 /// <param name="model">The model to be removed</param>
60- public static void Remove<T>(this IRepository<T> repository, T model) where T: IHasNameAndID
62+ public static void Remove<S,T>(this IRepository<S,T> repository, T model) where T: IHasNameAndID where S : IIdentifier
6163 {
62- repository.RemoveByID(model.ID);
64+ repository.RemoveByID((S) model.ID);
6365 }
6466
6567 /// <summary>
@@ -69,12 +71,12 @@
6971 /// <param name="repository"></param>
7072 /// <param name="model"></param>
7173 /// <returns>true if the model correspond to the id is exist.</returns>
72- public static bool HasID<T>(this IRepository<T> repository, T model) where T : class, IHasNameAndID
74+ public static bool HasID<S,T>(this IRepository<S,T> repository, T model) where T : class, IHasNameAndID where S : IIdentifier
7375 {
74- return repository[model.ID] != null;
76+ return repository[(S) model.ID] != null;
7577 }
7678
77- public static T findByID<T>(this IRepository<T> repository, string id, T _default = null) where T : class, IHasNameAndID
79+ public static T findByID<S,T>(this IRepository<S,T> repository, S id, T _default = null) where T : class, IHasNameAndID where S : IIdentifier
7880 {
7981 return repository[id] ?? _default;
8082 }
--- trunk/framework/framework/repository/IRepositoryBuilder.cs (revision 71)
+++ trunk/framework/framework/repository/IRepositoryBuilder.cs (revision 72)
@@ -11,8 +11,9 @@
1111 /// データリポジトリビルダーのインターフェース
1212 /// 標準実装はRepositoryBuilderBase
1313 /// </summary>
14+ /// <typeparam name="S"></typeparam>
1415 /// <typeparam name="T"></typeparam>
15- public interface IRepositoryBuilder<T> where T: IHasNameAndID
16+ public interface IRepositoryBuilder<S,T> where S: IIdentifier where T: IHasNameAndID
1617 {
1718 /// <summary>
1819 /// モデルを追加する。既にモデル
@@ -25,10 +26,10 @@
2526 /// </summary>
2627 /// <param name="id"></param>
2728 /// <returns>removed model or null if not exist</returns>
28- T RemoveByID(string id);
29+ T RemoveByID(S id);
2930
3031
31- IRepository<T> Finalize();
32+ IRepository<S,T> Finalize();
3233 }
3334
3435
--- trunk/framework/framework/repository/RepositoryBase.cs (revision 71)
+++ trunk/framework/framework/repository/RepositoryBase.cs (revision 72)
@@ -7,11 +7,11 @@
77
88 namespace nft.framework.repository
99 {
10- public class RepositoryBase<T> : IRepository<T> where T: class, IHasNameAndID
10+ public class RepositoryBase<S,T> : IRepository<S,T> where T: class, IHasNameAndID where S:IIdentifier
1111 {
12- protected Dictionary<string, T> dictionary = new Dictionary<string, T>();
12+ protected Dictionary<S, T> dictionary = new Dictionary<S, T>();
1313
14- public T this[string id]
14+ public T this[S id]
1515 {
1616 get
1717 {
@@ -39,10 +39,10 @@
3939
4040 public void Add(T model)
4141 {
42- dictionary.Add(model.ID, model);
42+ dictionary.Add((S)model.ID, model);
4343 }
4444
45- public T RemoveByID(string id)
45+ public T RemoveByID(S id)
4646 {
4747 T ret = this[id];
4848 dictionary.Remove(id);
--- trunk/framework/nftfw.resource.xml (revision 71)
+++ trunk/framework/nftfw.resource.xml (revision 72)
@@ -32,6 +32,7 @@
3232 Class={1}
3333 Method={2}
3434 </property>
35+ <proprety name="'{0}' contains invalid character(s) as a {1}.">'{0}' には {1} に使えない文字が含まれています。</proprety>
3536 <property name="An attribute '{1}' is required for the node '{0}'.">XMLノード[{0}]には[{1}]属性が必要です。
3637 ソース:{2}</property>
3738 <property name="Failed to create an instance of the class '{0}'.">指定されたクラス[{0}]のインスタンス作成に失敗しました。
--- trunk/framework/ui/command/CommandManager.cs (revision 71)
+++ trunk/framework/ui/command/CommandManager.cs (revision 72)
@@ -24,9 +24,9 @@
2424
2525 public static string MakeKey(IHasNameAndID owner, string suffix) {
2626 if (suffix != null && suffix.Length > 0)
27- return owner.ID + IDSuffixSepalator + suffix;
27+ return owner.ID.AsString + IDSuffixSepalator + suffix;
2828 else
29- return owner.ID;
29+ return owner.ID.AsString;
3030 }
3131
3232 [Obsolete]
--- trunk/framework/util/ContribListControlHelper.cs (revision 71)
+++ trunk/framework/util/ContribListControlHelper.cs (revision 72)
@@ -38,7 +38,7 @@
3838 if( index<0 || combo.Items.Count<index ) return null;
3939 AbstractItem item = combo.Items[index] as AbstractItem;
4040 if( item != null )
41- return PluginManager.theInstance.GetContribution(item.ID);
41+ return PluginManager.theInstance.GetContribution((VContributionId) item.ID);
4242 else
4343 return null;
4444 }
@@ -45,13 +45,13 @@
4545
4646 public static void SelectContribution(ComboBox combo, Contribution ctb) {
4747 if (ctb != null) {
48- SelectContribution(combo, ctb.ID);
48+ SelectContribution(combo, ctb.ContributionID);
4949 } else {
5050 combo.SelectedIndex = -1;
5151 }
5252 }
5353
54- public static void SelectContribution(ComboBox combo, string ctbID) {
54+ public static void SelectContribution(ComboBox combo, VContributionId ctbID) {
5555 if (ctbID != null) {
5656 for (int i = 0; i < combo.Items.Count; i++) {
5757 AbstractItem item = combo.Items[i] as AbstractItem;
@@ -111,7 +111,7 @@
111111 if (index < 0 || combo.Items.Count < index) return null;
112112 AbstractItem item = combo.Items[index] as AbstractItem;
113113 if (item != null)
114- return PluginManager.theInstance.GetContribution(item.ID) as T;
114+ return PluginManager.theInstance.GetContribution((VContributionId) item.ID) as T;
115115 else
116116 return null;
117117 }
@@ -119,7 +119,7 @@
119119 public void SelectContribution(ComboBox combo, T obj) {
120120 IHasNameAndID ctb = obj as IHasNameAndID;
121121 if (ctb != null) {
122- SelectContribution(combo, ctb.ID);
122+ SelectContribution(combo, ctb.ID.AsString);
123123 } else {
124124 combo.SelectedIndex = -1;
125125 }
@@ -154,7 +154,7 @@
154154 sealed class AbstractItem
155155 {
156156 public readonly string Name;
157- public readonly string ID;
157+ public readonly IIdentifier ID;
158158 public AbstractItem( IHasNameAndID entity )
159159 {
160160 this.Name = entity.Name;
--- trunk/framework/util/ObjectExtensions.cs (nonexistent)
+++ trunk/framework/util/ObjectExtensions.cs (revision 72)
@@ -0,0 +1,48 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Linq;
4+using System.Reflection;
5+using System.Text;
6+using System.Threading.Tasks;
7+
8+namespace nft.util
9+{
10+ static class ObjectExtensions
11+ {
12+ private const string SEPARATOR = ","; // 区切り記号として使用する文字列
13+ private const string FORMAT = "{0}:{1}"; // 複合書式指定文字列
14+
15+ /// <summary>
16+ /// すべての公開フィールドの情報を文字列にして返します
17+ /// </summary>
18+ public static string ToStringFields<T>(this T obj)
19+ {
20+ return string.Join(SEPARATOR, obj
21+ .GetType()
22+ .GetFields(BindingFlags.Instance | BindingFlags.Public)
23+ .Select(c => string.Format(FORMAT, c.Name, c.GetValue(obj))));
24+ }
25+
26+ /// <summary>
27+ /// すべての公開プロパティの情報を文字列にして返します
28+ /// </summary>
29+ public static string ToStringProperties<T>(this T obj)
30+ {
31+ return string.Join(SEPARATOR, obj
32+ .GetType()
33+ .GetProperties(BindingFlags.Instance | BindingFlags.Public)
34+ .Where(c => c.CanRead)
35+ .Select(c => string.Format(FORMAT, c.Name, c.GetValue(obj, null))));
36+ }
37+
38+ /// <summary>
39+ /// すべての公開フィールドと公開プロパティの情報を文字列にして返します
40+ /// </summary>
41+ public static string ToStringReflection<T>(this T obj)
42+ {
43+ return string.Join(SEPARATOR,
44+ obj.ToStringFields(),
45+ obj.ToStringProperties());
46+ }
47+ }
48+}
--- trunk/mainframe/ui/docking/IDockContentFactory.cs (revision 71)
+++ trunk/mainframe/ui/docking/IDockContentFactory.cs (revision 72)
@@ -16,7 +16,7 @@
1616 int n = persist.IndexOf(SepalatorPersist);
1717 string id = persist.Substring(0, n);
1818 string nam = persist.Substring(n + SepalatorPersist.Length);
19- Contribution ctb = PluginManager.theInstance.GetContribution(id);
19+ Contribution ctb = PluginManager.theInstance.GetContribution(new VContributionId(id));
2020 IDockContentFactory fct = ctb as IDockContentFactory;
2121 if (fct != null) {
2222 return fct.CreateDockContent(nam);
--- trunk/ui_jp/ui/core/BuildTool.cs (revision 71)
+++ trunk/ui_jp/ui/core/BuildTool.cs (revision 72)
@@ -17,7 +17,8 @@
1717 }
1818
1919 protected void LoadCatalog(){
20- CtbStructureSkinCatalog ctb = PluginManager.theInstance.GetContribution(@"system\C_StructureSkinCatalog") as CtbStructureSkinCatalog;
20+ VContributionId idCatalog = new VContributionId(VPluginId.System, "C_StructureSkinCatalog");
21+ CtbStructureSkinCatalog ctb = PluginManager.theInstance.GetContribution(idCatalog) as CtbStructureSkinCatalog;
2122
2223 SkinCatalog catalog = ctb.Catalog;
2324 }
--- trunk/ui_jp/ui/system/PluginListDialog.cs (revision 71)
+++ trunk/ui_jp/ui/system/PluginListDialog.cs (revision 72)
@@ -538,7 +538,7 @@
538538 private ListViewItem CreateListItem(Contribution c)
539539 {
540540 int icon = GetIconIndex(c);
541- ListViewItem item = new ListViewItem(new string[]{ c.Name ,c.CtbType, c.ID }, icon );
541+ ListViewItem item = new ListViewItem(new string[]{ c.Name ,c.CtbType, c.ID.AsString }, icon );
542542 item.Tag = c;
543543 item.Checked = c.IsAttached;
544544 return item;
@@ -546,7 +546,7 @@
546546 private ListViewItem CreateListItem(Plugin p)
547547 {
548548 int icon = GetIconIndex(p);
549- ListViewItem item = new ListViewItem(new string[]{ p.Title, p.author, p.ID }, icon );
549+ ListViewItem item = new ListViewItem(new string[]{ p.Title, p.author, p.ID.AsString }, icon );
550550 item.Tag = p;
551551 item.Checked = p.IsAttached;
552552
@@ -674,7 +674,7 @@
674674 }
675675 private TreeNode CreateTreeItem(Plugin p) {
676676 int icon = GetIconIndex(p);
677- TreeNode node = new TreeNode(p.ID, icon, icon);
677+ TreeNode node = new TreeNode(p.ID.AsString, icon, icon);
678678 node.Tag = p;
679679 node.Checked = p.IsAttached;
680680 return node;