1
|
1 package rep;
|
|
2
|
213
|
3 import java.util.ArrayList;
|
122
|
4 import java.util.LinkedList;
|
142
|
5 import java.util.List;
|
1
|
6
|
131
|
7 import rep.channel.REPSocketChannel;
|
224
|
8 import rep.optimizers.*;
|
142
|
9 import rep.translater.TranslaterImp1;
|
131
|
10
|
1
|
11 public class Editor {
|
281
|
12 private int eid; // unique id in a session
|
|
13 private int sid = -1 ; // globally unique session id
|
132
|
14 private REPSocketChannel<REPCommand> myChannel;
|
21
|
15 private String host;
|
39
|
16 private String file;
|
142
|
17 private TranslaterImp1 translater;
|
|
18 private List<REPCommand> sentList;
|
213
|
19 private List<REPCommand> sentMergedList;
|
224
|
20 private REPCommandOptimizer optimizer;
|
155
|
21
|
|
22 public Editor(){
|
224
|
23 this(true);
|
|
24 }
|
|
25 public Editor(boolean doOptimize){
|
155
|
26 setHostAndPort(myChannel);
|
|
27 translater = new TranslaterImp1(eid);
|
|
28 sentList = new LinkedList<REPCommand>();
|
265
|
29 sentMergedList = new LinkedList<REPCommand>();
|
224
|
30
|
|
31 if (doOptimize) optimizer = new DeleteInsertOptimizer(); //タカノがつくったおぷてぃまいざ
|
|
32 else optimizer = new NullOptimizer(); //なにもしないけどOptimizer.
|
|
33
|
155
|
34 }
|
1
|
35
|
132
|
36 public Editor(int editorNo, REPSocketChannel<REPCommand> channel){
|
23
|
37 this.eid = editorNo;
|
56
|
38 this.myChannel = channel;
|
142
|
39 translater = new TranslaterImp1(eid);
|
|
40 sentList = new LinkedList<REPCommand>();
|
265
|
41 sentMergedList = new LinkedList<REPCommand>();
|
152
|
42 setHostAndPort(myChannel);
|
56
|
43 }
|
142
|
44
|
132
|
45 public Editor(REPSocketChannel<REPCommand> channel) {
|
56
|
46 this.myChannel = channel;
|
|
47 setHostAndPort(myChannel);
|
152
|
48 translater = new TranslaterImp1(eid);
|
|
49 sentList = new LinkedList<REPCommand>();
|
56
|
50 }
|
142
|
51
|
224
|
52 public List<REPCommand> translate(REPCommand command){
|
|
53 List<REPCommand> list = new LinkedList<REPCommand>();
|
142
|
54 if(command.eid == eid){
|
|
55 if(checkReturnedCommand(command)){
|
152
|
56 //エディタからのコマンドが元のエディタに戻ってきた
|
164
|
57 //マージして送信
|
213
|
58 ArrayList<REPCommand> cmds = translater.catchOwnCommand(command);
|
|
59 //optimizer
|
|
60 //マージ中のエディタからの割り込み検知に使う
|
|
61 sentMergedList.addAll(cmds);
|
142
|
62 sendMergedCommand(cmds);
|
265
|
63 return list;
|
142
|
64 }else{
|
152
|
65 //エディタからの新たな編集コマンド
|
142
|
66 sentList.add(command);
|
|
67 translater.transSendCmd(command);
|
|
68 list.add(command);
|
|
69 }
|
271
|
70 }else if(eid == REP.MERGE_EID.id){
|
179
|
71 //マージコマンドが返ってきた
|
|
72 if(translater.checkMergeConflict(command)){
|
|
73 //マージ中にエディタからの割り込みがあった場合
|
224
|
74 List<REPCommand> mergeAgainList = translater.getMergeAgain();
|
|
75
|
|
76 mergeAgainList = optimizer.optimize(mergeAgainList);
|
179
|
77 for(REPCommand againCommand: mergeAgainList){
|
|
78 myChannel.write(againCommand);
|
|
79 }
|
|
80 }
|
142
|
81 }else{
|
152
|
82 //他のエディタからの編集コマンド
|
142
|
83 REPCommand[] cmds = translater.transReceiveCmd(command);
|
|
84 for(REPCommand cmd : cmds){
|
|
85 list.add(cmd);
|
|
86 }
|
|
87 }
|
|
88 return list;
|
|
89 }
|
|
90
|
213
|
91 private void sendMergedCommand(ArrayList<REPCommand> cmds) {
|
278
|
92 // 一気に送ると、向こう側(Editor)で、dead lock する可能性がある。
|
|
93 // select loop の中で一つ一つ送るしかない。Editor側から割り込まれる可能性も
|
|
94 // ある。その時に複数のコマンドを送っていると、どこに割り込まれたかを判断する
|
|
95 // ことが出来ない。そこで、一つ一つReturnを確認する必要がある。つまり、
|
|
96 // select loop で送るしかない。
|
213
|
97 for(REPCommand mergeCommand : cmds){
|
271
|
98 mergeCommand.setEID(REP.MERGE_EID.id);
|
179
|
99 myChannel.write(mergeCommand);
|
142
|
100 }
|
|
101 }
|
56
|
102
|
142
|
103 private boolean checkReturnedCommand(REPCommand command) {
|
|
104 if(sentList.size() > 0){
|
|
105 if(sentList.get(0).seq == command.seq){
|
|
106 sentList.remove(0);
|
|
107 return true;
|
|
108 }else{
|
275
|
109 System.err.println("error:Editor.checkReturnedCommand()");
|
142
|
110 }
|
|
111 }
|
|
112 return false;
|
74
|
113 }
|
|
114
|
132
|
115 private void setHostAndPort(REPSocketChannel<REPCommand> myChannel2) {
|
195
|
116 //host = myChannel2.socket().getRemoteSocketAddress().toString();
|
178
|
117
|
1
|
118 }
|
|
119
|
132
|
120 public REPSocketChannel<REPCommand> getChannel() {
|
56
|
121 return myChannel;
|
1
|
122 }
|
21
|
123
|
|
124 public void setHost(String host){
|
|
125 this.host = host;
|
|
126 }
|
178
|
127
|
21
|
128
|
|
129 public String getHost(){
|
|
130 return host;
|
|
131 }
|
178
|
132
|
21
|
133
|
23
|
134 public int getEID() {
|
|
135 return eid;
|
|
136 }
|
|
137
|
|
138 public void setEID(int eid) {
|
|
139 this.eid = eid;
|
|
140 }
|
24
|
141 public String toString(){
|
178
|
142 return (host + ":" + file);
|
24
|
143 }
|
23
|
144
|
38
|
145 public String getName() {
|
39
|
146 return file;
|
|
147 }
|
|
148
|
|
149 public void setName(String string) {
|
|
150 file = string;
|
38
|
151 }
|
|
152
|
179
|
153 public void send(REPCommand command) {
|
|
154 myChannel.write(command);
|
56
|
155 }
|
|
156
|
178
|
157 public void setChannel(REPSocketChannel<REPCommand> channel) {
|
83
|
158 myChannel = channel;
|
|
159 }
|
|
160
|
164
|
161 public boolean isMerging() {
|
|
162 return translater.isMerging();
|
|
163 }
|
281
|
164 public boolean hasSession() {
|
|
165 return sid != -1;
|
|
166 }
|
|
167 public void setSID(int sessionID) {
|
|
168 sid = sessionID;
|
|
169 }
|
164
|
170
|
1
|
171 }
|