source: simplerunner/src/main/java/geniusweb/simplerunner/ClassPathConnectionFactory.java@ 52

Last change on this file since 52 was 52, checked in by ruud, 14 months ago

Fixed small issues in domaineditor.

File size: 6.0 KB
Line 
1package geniusweb.simplerunner;
2
3import java.io.IOException;
4import java.lang.reflect.Constructor;
5import java.lang.reflect.InvocationTargetException;
6import java.net.URI;
7import java.net.URISyntaxException;
8import java.util.LinkedList;
9import java.util.List;
10
11import geniusweb.actions.Action;
12import geniusweb.actions.PartyId;
13import geniusweb.inform.Inform;
14import geniusweb.party.Party;
15import geniusweb.protocol.partyconnection.ProtocolToPartyConn;
16import geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory;
17import geniusweb.references.Reference;
18import tudelft.utilities.repository.NoResourcesNowException;
19
20/**
21 * A connectionfactory that only accepts URLs of the form
22 * <code>classpath:org/my/package/class</code>
23 *
24 */
25public class ClassPathConnectionFactory implements ProtocolToPartyConnFactory {
26 private List<ConnectionPair> allConnections = new LinkedList<>();
27
28 /**
29 * @param reference the party class path reference4
30 */
31 @Override
32 public ProtocolToPartyConn connect(Reference reference) {
33 ConnectionPair connpair = new ConnectionPair(reference);
34 allConnections.add(connpair);
35 return connpair.getProtocolToPartyConn();
36 }
37
38 @Override
39 public List<ProtocolToPartyConn> connect(List<Reference> references)
40 throws IOException, NoResourcesNowException {
41 List<ProtocolToPartyConn> connections = new LinkedList<>();
42 for (Reference partyref : references) {
43 connections.add(connect(partyref));
44 }
45 return connections;
46 }
47
48 /**
49 * @return list of connections that are still open.
50 */
51 public List<BasicConnection> getOpenConnections() {
52 List<BasicConnection> open = new LinkedList<>();
53 for (ConnectionPair connpair : allConnections) {
54 open.addAll(connpair.getOpenConnections());
55 }
56 return open;
57 }
58
59}
60
61class BasicConnectionWithParty extends BasicConnection<Action, Inform>
62 implements ProtocolToPartyConn {
63
64 private PartyId id;
65
66 public BasicConnectionWithParty(Reference reference, URI uri) {
67 super(reference, uri);
68 this.id = new PartyId(uri.toString().replace("classpath:", "")
69 .replaceAll("\\.", "_"));
70 }
71
72 @Override
73 public PartyId getParty() {
74 return id;
75 }
76
77 @Override
78 public String toString() {
79 return "WP" + super.toString();
80 }
81
82}
83
84/**
85 * Contains the connection from protocol to party and from party to protocol.
86 * These two are dependent on each other, and must close together.
87 *
88 */
89class ConnectionPair {
90 private static int serialcounter = 1;
91 private static final String SCHEME = "classpath";
92 private final static URI PROTOCOLURI = uri("protocol:protocol");
93
94 private final BasicConnection<Inform, Action> party2protocol;
95 private final BasicConnectionWithParty protocol2party;
96
97 /**
98 *
99 * @param reference the party class path reference4
100 *
101 */
102 public ConnectionPair(Reference reference) {
103 // set up the whole other party including the connection to it.
104 String classpath = getClassPath(reference.getURI());
105 Party party = instantiate(classpath);
106
107 // if call to protocol would fail, we should also close the
108 // protocol2party connection. But we assume that will work fine.
109 party2protocol = new BasicConnection<Inform, Action>(reference,
110 PROTOCOLURI) {
111
112 @Override
113 public void close() {
114 if (isOpen()) {
115 super.close();
116 protocol2party.close();
117 }
118 }
119
120 };
121
122 // if callback from protocol to party fails, then also close the
123 // other direction.
124 protocol2party = new BasicConnectionWithParty(reference,
125 uri("classpath:" + reference.getURI().getSchemeSpecificPart()
126 + "." + (serialcounter++))) {
127 @Override
128 public void close() {
129 if (isOpen()) {
130 super.close();
131 party2protocol.close();
132 }
133 }
134
135 };
136
137 party2protocol.init(action -> protocol2party.notifyListeners(action));
138
139 protocol2party.init(info -> party2protocol.notifyListeners(info));
140
141 party.connect(party2protocol);
142
143 }
144
145 /**
146 *
147 * @return the open connections
148 */
149 public List<BasicConnection> getOpenConnections() {
150 List<BasicConnection> open = new LinkedList<>();
151 if (party2protocol.isOpen())
152 open.add(party2protocol);
153 if (protocol2party.isOpen())
154 open.add(protocol2party);
155 return open;
156 }
157
158 public BasicConnectionWithParty getProtocolToPartyConn() {
159 return protocol2party;
160 }
161
162 /**
163 * Internal use for testing
164 */
165 protected BasicConnection getPartyToProtocolConn() {
166 return party2protocol;
167 }
168
169 /**
170 *
171 * @param classpath
172 * @return instance of the given {@link Party} on the classpath
173 * @throws IllegalArgumentException if the Party can not be instantiated, eg
174 * because of a ClassCastException,
175 * ClassNotFoundException,
176 * IllegalAccessException etc. Such an
177 * exception is considered a bug by the
178 * programmer, because this is a
179 * stand-alone runner.
180 */
181 @SuppressWarnings("unchecked")
182 private Party instantiate(String classpath) {
183 System.out.println("Connecting with party '" + classpath + "'");
184 Class<Party> partyclass;
185 try {
186 partyclass = (Class<Party>) Class.forName(classpath);
187 Constructor<Party> ctor = partyclass.getConstructor();
188 return ctor.newInstance(new Object[] {});
189 } catch (ClassNotFoundException | NoSuchMethodException
190 | SecurityException | InstantiationException
191 | IllegalAccessException | IllegalArgumentException
192 | InvocationTargetException e) {
193 throw new IllegalArgumentException(
194 "Failed to create connection to party " + classpath, e);
195 }
196
197 }
198
199 private static URI uri(String ref) {
200 try {
201 return new URI(ref);
202 } catch (URISyntaxException e) {
203 throw new IllegalStateException("failed to create basic URI", e);
204 }
205 }
206
207 private String getClassPath(URI uri) {
208 if (!SCHEME.equals(uri.getScheme())) {
209 throw new IllegalArgumentException("Required the " + SCHEME
210 + " protocol but found " + uri.getScheme());
211 }
212 String path = uri.getSchemeSpecificPart();
213 if (path == null) {
214 throw new IllegalArgumentException(
215 "Expected classpath but found null in " + uri);
216 }
217 return path;
218 }
219
220}
Note: See TracBrowser for help on using the repository browser.