View Javadoc

1   /*
2    * Copyright (c) 2006 Stiftung Deutsches Elektronen-Synchroton, Member of the Helmholtz
3    * Association, (DESY), HAMBURG, GERMANY. THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON
4    * AN "../AS IS" BASIS. WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT
5    * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND
6    * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
7    * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
8    * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9    * THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, THE USER ASSUMES THE
10   * COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY
11   * CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SOFTWARE IS AUTHORIZED
12   * HEREUNDER EXCEPT UNDER THIS DISCLAIMER. DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
13   * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. THE FULL LICENSE SPECIFYING FOR THE
14   * SOFTWARE THE REDISTRIBUTION, MODIFICATION, USAGE AND OTHER RIGHTS AND OBLIGATIONS IS
15   * INCLUDED WITH THE DISTRIBUTION OF THIS PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE
16   * IS NOT INCLUDED YOU MAY FIND A COPY AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM
17   */
18  
19  package de.desy.acop.transport;
20  
21  import java.io.Serializable;
22  import java.util.ArrayList;
23  
24  /**
25   * This objecct holds all parameters necessary to initiate ACOP transport connection.
26   * 
27   * @author Igor Kriznar (igor.kriznarATcosylab.com)
28   */
29  public class ConnectionParameters implements Comparable<ConnectionParameters>, Serializable {
30  	/**
31  	 * Predefined value for the property size connection parameter, which means that when
32  	 * property will be connected, then actual remote size for property array will be
33  	 * used.
34  	 */
35  	public static int ACTUAL_PROPERTY_SIZE = 0;
36  	/**
37  	 * Predefined value for the property size connection parameter, which means that when
38  	 * property will be connected, size of array will be set according to displayer's
39  	 * capabilities.
40  	 */
41  	public static int AUTO_PROPERTY_SIZE = -1;
42  
43  	private static final long serialVersionUID = -430933461297463309L;
44  	private String accessProtocol;
45  	private String deviceContext;
46  	private String deviceGroup;
47  	private String deviceName;
48  	private String deviceProperty;
49  	private AccessMode accessMode;
50  	private int accessRate;
51  
52  	private int propertySize = AUTO_PROPERTY_SIZE;
53  
54  	private Object dynamicParameters;
55  
56  	/**
57  	 * Creates new instance of ConnectionParameters.
58  	 */
59  	public ConnectionParameters() {}
60  
61  	/**
62  	 * Constructs a new ConnectionParameters. This constructor assume that the given
63  	 * paramete string includes the remote name which is obligatory as well as AccessMode,
64  	 * access rate and property size, which is optional (all three included or excluded).
65  	 * The parameter can also include everything but the property size. All parameters in
66  	 * the string should be separated by comma (eg.
67  	 * PROTOCOL/CONTEXT/SERVER/DEVICE/PROPERTY,AccessMode.POLL,1000,1).
68  	 * 
69  	 * @param parameters
70  	 * @see #getPropertySize()
71  	 */
72  	public ConnectionParameters(String parameters) {
73  		String[] p = parameters.split(",");
74  		if (p == null) {
75  			throw new IllegalArgumentException("Could not construct connection parameters. The provided remote name is null.");
76  		}
77  		//the following code solves problems with comma in the device name
78  		if (p.length > 1) {
79  			StringBuilder remoteName = new StringBuilder(p[0]);
80  			int i = 1;
81  			int j = p.length-1;
82  			//Find out where the property is located (the last element that contains
83  			//the /). Anything before that is definitely part of the remote name.
84  			for (; j > -1; j--) {
85  				if (p[j].contains("/")) break;
86  			}
87  			for (; i < p.length; i++) {
88  				if (p[i].contains("/") || i <= j) {
89  					remoteName.append(',');
90  					remoteName.append(p[i]);
91  				} else {
92  					try {
93  						//if we hit the access mode, we are through with the remotename concatenation
94  						AccessMode.valueOf(p[i]);
95  						break;
96  					} catch (IllegalArgumentException e) {
97  						try {
98  							//if we hit a number, we are through with the remotename concatenation
99  							Integer.parseInt(p[i]);
100 							break;
101 						} catch (NumberFormatException ex) {
102 							remoteName.append(',');
103 							remoteName.append(p[i]);
104 						}
105 					}
106 				}
107 			}
108 			//construct a new array with all the stuff combined
109 			ArrayList<String> param = new ArrayList<String>();
110 			param.add(remoteName.toString());
111 			for (; i < p.length; i++) {
112 				param.add(p[i]);
113 			}
114 			p = param.toArray(new String[param.size()]);
115 		}
116 		if (p.length == 4) {
117 			setUpRemoteName(p[0]);
118 			this.accessMode = AccessMode.valueOf(p[1]);
119 			this.accessRate = Integer.parseInt(p[2]);
120 			this.propertySize = Integer.parseInt(p[3]);
121 		} else if (p.length == 1) {
122 			setUpRemoteName(p[0]);
123 			this.accessMode = AccessMode.POLL;
124 			this.accessRate = 1000;
125 			this.propertySize = AUTO_PROPERTY_SIZE;
126 		} else if (p.length == 3) {
127 			setUpRemoteName(p[0]);
128 			this.accessMode = AccessMode.valueOf(p[1]);
129 			this.accessRate = Integer.parseInt(p[2]);
130 		} else {
131 			throw new IllegalArgumentException("Failed to construct connection parameters. The string should contain 1, 3, or 4 elements separated by comma.");
132 		}
133 	}
134 	
135 	/**
136 	 * @see #ConnectionParameters(String)
137 	 * @param parameters the parameters (remotename,accessmode,accessrate,propertySize)
138 	 * @param dynamicParameters additional parameters that are required for making a
139 	 *        connection
140 	 */
141 	public ConnectionParameters(String parameters, Object dynamicParameters) {
142 		this(parameters);
143 		this.dynamicParameters = dynamicParameters;
144 	}
145 
146 	/**
147 	 * Creates new instance of ConnectionParameters.
148 	 * 
149 	 * @param accessProtocol the access protocol (TINE)
150 	 * @param deviceContext the context
151 	 * @param deviceGroup the server
152 	 * @param deviceName the device name
153 	 * @param deviceProperty the property name
154 	 * @param accessMode the access mode for the connection
155 	 * @param accessRate the polling rate
156 	 */
157 	public ConnectionParameters(String accessProtocol, String deviceContext, String deviceGroup, String deviceName, String deviceProperty,
158 			AccessMode accessMode, int accessRate) {
159 		super();
160 		this.accessProtocol = accessProtocol != null ? accessProtocol : "";
161 		this.deviceContext = deviceContext != null ? deviceContext : "";
162 		this.deviceGroup = deviceGroup != null ? deviceGroup : "";
163 		this.deviceName = deviceName != null ? deviceName : "";
164 		this.deviceProperty = deviceProperty != null ? deviceProperty : "";
165 		this.accessMode = accessMode;
166 		this.accessRate = accessRate;
167 	}
168 
169 	/**
170 	 * 
171 	 * @see #ConnectionParameters(String, String, String, String, String, AccessMode, int)
172 	 * @param accessProtocol the access protocol (TINE)
173 	 * @param deviceContext the context
174 	 * @param deviceGroup the server
175 	 * @param deviceName the device name
176 	 * @param deviceProperty the property name
177 	 * @param accessMode the access mode for the connection
178 	 * @param accessRate the polling rate
179 	 * @param dynamicParameters additional parameters to make a connection
180 	 */
181 	public ConnectionParameters(String accessProtocol, String deviceContext, String deviceGroup, String deviceName, String deviceProperty,
182 			AccessMode accessMode, int accessRate, Object dynamicParameters) {
183 		this(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate);
184 		this.dynamicParameters = dynamicParameters;
185 	}
186 
187 	/**
188 	 * Constructs a new ConnectionParameters.
189 	 * 
190 	 * @param accessProtocol the access protocol (TINE)
191 	 * @param deviceContext the context
192 	 * @param deviceGroup the server
193 	 * @param deviceName the device name
194 	 * @param deviceProperty the property name
195 	 * @param accessMode the access mode for the connection
196 	 * @param accessRate the polling rate
197 	 * @param propertySize the size of the requested property data
198 	 */
199 	public ConnectionParameters(String accessProtocol, String deviceContext, String deviceGroup, String deviceName, String deviceProperty,
200 			AccessMode accessMode, int accessRate, int propertySize) {
201 		this(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate);
202 		this.propertySize = propertySize;
203 	}
204 
205 	/**
206 	 * @see #ConnectionParameters(String, String, String, String, String, AccessMode, int, int)
207 	 * @param accessProtocol the access protocol (TINE)
208 	 * @param deviceContext the context
209 	 * @param deviceGroup the server
210 	 * @param deviceName the device name
211 	 * @param deviceProperty the property name
212 	 * @param accessMode the access mode for the connection
213 	 * @param accessRate the polling rate
214 	 * @param propertySize the size of the requested property data
215 	 * @param dynamicParameters additional parameters to make a connection
216 	 */
217 	public ConnectionParameters(String accessProtocol, String deviceContext, String deviceGroup, String deviceName, String deviceProperty,
218 			AccessMode accessMode, int accessRate, int propertySize, Object dynamicParameters) {
219 		this(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,propertySize);
220 		this.dynamicParameters = dynamicParameters;
221 	}
222 
223 	/**
224 	 * Creates new instance of ConnectionParameters.
225 	 * 
226 	 * @param remoteName the remote name (context/server/device/property)
227 	 * @param accessMode the access mode for the connection
228 	 * @param accessRate the polling rate
229 	 */
230 	public ConnectionParameters(String remoteName, AccessMode accessMode, int accessRate) {
231 		super();
232 		setUpRemoteName(remoteName);
233 		this.accessMode = accessMode;
234 		this.accessRate = accessRate;
235 	}
236 
237 	/**
238 	 * @see #ConnectionParameters(String, AccessMode, int)
239 	 * 
240 	 * @param remoteName the remote name (context/server/device/property)
241 	 * @param accessMode the access mode for the connection
242 	 * @param accessRate the polling rate
243 	 * @param dynamicParameters additional parameters to make a connection
244 	 */
245 	public ConnectionParameters(String remoteName, AccessMode accessMode, int accessRate, Object dynamicParameters) {
246 		this(remoteName,accessMode, accessRate);
247 		this.dynamicParameters = dynamicParameters;
248 	}
249 	
250 	private void setUpRemoteName(String remoteName) {
251 		String[] s = remoteName.split("/");
252 
253 		this.accessProtocol = (s.length > 0 && s[0] != null) ? s[0] : "";
254 		this.deviceContext = (s.length > 1 && s[1] != null) ? s[1] : "";
255 		this.deviceGroup = (s.length > 2 && s[2] != null) ? s[2] : "";
256 		this.deviceProperty = (s.length > 4 && s[s.length - 1] != null) ? s[s.length - 1] : "";
257 
258 		StringBuilder sb = new StringBuilder(128);
259 
260 		if (s.length > 3 && s[3] != null) {
261 			sb.append(s[3]);
262 		}
263 		for (int i = 4; i < s.length - 1; i++) {
264 			sb.append('/');
265 			if (s[i] != null) sb.append(s[i]);
266 		}
267 
268 		this.deviceName = sb.toString();
269 	}
270 
271 	/**
272 	 * Constructs new ConnectionParameters object.
273 	 * 
274 	 * @param remoteName the remote name (context/server/device/property)
275 	 * @param accessMode the access mode for the connection
276 	 * @param accessRate the polling rate
277 	 * @param arraySize the size of the requested data array
278 	 */
279 	public ConnectionParameters(String remoteName, AccessMode accessMode, int accessRate, int arraySize) {
280 		this(remoteName,accessMode,accessRate);
281 		this.propertySize = arraySize;
282 	}
283 	
284 	/**
285 	 * @see #ConnectionParameters(String, AccessMode, int, int)
286 	 * 
287 	 * @param remoteName the remote name (context/server/device/property)
288 	 * @param accessMode the access mode for the connection
289 	 * @param accessRate the polling rate
290 	 * @param arraySize the size of the requested data array
291 	 * @param dynamicParameters additional parameters to make a connection
292 	 */
293 	public ConnectionParameters(String remoteName, AccessMode accessMode, int accessRate, int arraySize, Object dynamicParameters) {
294 		this(remoteName, accessMode, accessRate, arraySize);
295 		this.dynamicParameters = dynamicParameters;
296 	}
297 
298 	/**
299 	 * Returns the accessMode.
300 	 * 
301 	 * @return Returns the accessMode.
302 	 */
303 	public AccessMode getAccessMode() {
304 		return accessMode;
305 	}
306 
307 	/**
308 	 * Returns the accessProtocol.
309 	 * 
310 	 * @return Returns the accessProtocol.
311 	 */
312 	public String getAccessProtocol() {
313 		return accessProtocol;
314 	}
315 
316 	/**
317 	 * Returns the accessRate.
318 	 * 
319 	 * @return Returns the accessRate.
320 	 */
321 	public int getAccessRate() {
322 		return accessRate;
323 	}
324 
325 	/**
326 	 * Returns the deviceContext.
327 	 * 
328 	 * @return Returns the deviceContext.
329 	 */
330 	public String getDeviceContext() {
331 		return deviceContext;
332 	}
333 
334 	/**
335 	 * Returns the deviceGroup.
336 	 * 
337 	 * @return Returns the deviceGroup.
338 	 */
339 	public String getDeviceGroup() {
340 		return deviceGroup;
341 	}
342 
343 	/**
344 	 * Returns the deviceName.
345 	 * 
346 	 * @return Returns the deviceName.
347 	 */
348 	public String getDeviceName() {
349 		return deviceName;
350 	}
351 
352 	/**
353 	 * Returns the deviceProperty.
354 	 * 
355 	 * @return Returns the deviceProperty.
356 	 */
357 	public String getDeviceProperty() {
358 		return deviceProperty;
359 	}
360 
361 	/*
362 	 * (non-Javadoc)
363 	 * @see java.lang.Object#toString()
364 	 */
365 	public String toString() {
366 		return getRemoteName() + "," + accessMode + "," + accessRate + "," + propertySize;
367 	}
368 
369 	/**
370 	 * Return URI ready name for remote TINE property.
371 	 * 
372 	 * @return remote TINE name delimitted with / characters
373 	 */
374 	public String getRemoteName() {
375 		return accessProtocol + "/" + deviceContext + "/" + deviceGroup + "/" + deviceName + "/" + deviceProperty;
376 	}
377 
378 	/**
379 	 * Returns the dynamic parameters. These are the additional parameters, which might be
380 	 * required by the server to establish a connection. In normal conditions this is
381 	 * null, but it can be something like an int array.
382 	 * 
383 	 * @return the dynamic parameters
384 	 */
385 	public Object getDynamicParameters() {
386 		return dynamicParameters;
387 	}
388 	
389 	/**
390 	 * Size of TINE property. 1 means that property will have one value in array. -1 or 0
391 	 * means that when connected, automatic or actual property size will be used.
392 	 * 
393 	 * @return size or property if it is array
394 	 * @see #ACTUAL_PROPERTY_SIZE
395 	 * @see #AUTO_PROPERTY_SIZE
396 	 */
397 	public int getPropertySize() {
398 		return propertySize;
399 	}
400 
401 	/*
402 	 * (non-Javadoc)
403 	 * @see java.lang.Comparable#compareTo(java.lang.Object)
404 	 */
405 	public int compareTo(ConnectionParameters o) {
406 		if (o == null) return -1;
407 		return this.toString().compareTo(o.toString());
408 	}
409 
410 	/*
411 	 * (non-Javadoc)
412 	 * @see java.lang.Object#hashCode()
413 	 */
414 	public int hashCode() {
415 		return toString().hashCode();
416 	}
417 
418 	/*
419 	 * (non-Javadoc)
420 	 * @see java.lang.Object#equals(java.lang.Object)
421 	 */
422 	public boolean equals(Object o) {
423 		if (!(o instanceof ConnectionParameters)) return false;
424 		return this.toString().equals(o.toString());
425 		//    ConnectionParameters p = (ConnectionParameters) o;
426 		//    return (getRemoteName().equals(p.getRemoteName()) && accessMode.equals(p.getAccessMode()) && accessRate == p
427 		//        .getAccessRate());
428 	}
429 
430 	/**
431 	 * Returns new ConnectionParameters which resembles this object but has a different
432 	 * access mode.
433 	 * 
434 	 * @param mode access mode of the new parameters
435 	 * @return new ConnectionParameters object
436 	 */
437 	public ConnectionParameters deriveWith(AccessMode mode) {
438 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,mode,accessRate,propertySize,dynamicParameters);
439 	}
440 
441 	/**
442 	 * Returnst new ConnectionParameters which resembles this object but has a different
443 	 * acces mode and rate.
444 	 * 
445 	 * @param mode access mode of the new parameters
446 	 * @param rate access rate of the new parameters
447 	 * @return new COnnectionParameters object
448 	 */
449 	public ConnectionParameters deriveWith(AccessMode mode, int rate) {
450 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,mode,rate,propertySize,dynamicParameters);
451 	}
452 
453 	/**
454 	 * Returnst new ConnectionParameters which resembles this object but has a different
455 	 * and rate.
456 	 * 
457 	 * @param rate access rate of the new parameters
458 	 * @return new COnnectionParameters object
459 	 * @deprecated use {@link #deriveWithAccessRate(int)} instead
460 	 */
461 	public ConnectionParameters deriveWith(int rate) {
462 		return deriveWithAccessRate(rate);
463 	}
464 
465 	/**
466 	 * Returns new ConnectionParameters which resebles this object but has a
467 	 * different dynamic parameters.
468 	 * 
469 	 * @param newDynamicParameters the new dynamic parameters
470 	 * @return new connection parameters
471 	 */
472 	public ConnectionParameters deriveWithDynamicParameters(Object newDynamicParameters) {
473 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,
474 				propertySize,newDynamicParameters);
475 	}
476 
477 	/**
478 	 * Returns new ConnectionParameters which resembles this object but has a different
479 	 * property size.
480 	 * 
481 	 * @param propertySize the new property size
482 	 * @return new ConnectionParameters object
483 	 */
484 	public ConnectionParameters deriveWithPropertySize(int propertySize) {
485 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,
486 				propertySize,dynamicParameters);
487 	}
488 
489 	/**
490 	 * Constructs a new ConnectionParameters with the same properties as this object but a
491 	 * different access protocol.
492 	 * 
493 	 * @param accessProtocol new access protocol
494 	 * @return new ConnectionParameters object
495 	 */
496 	public ConnectionParameters deriveWithAccessProtocol(String accessProtocol) {
497 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,
498 				propertySize, dynamicParameters);
499 	}
500 
501 	/**
502 	 * Constructs a new ConnectionParameters with the same properties as this object but a
503 	 * different device context.
504 	 * 
505 	 * @param deviceContext new device context
506 	 * @return new ConnectionParameters object
507 	 */
508 	public ConnectionParameters deriveWithDeviceContext(String deviceContext) {
509 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,
510 				propertySize, dynamicParameters);
511 	}
512 
513 	/**
514 	 * Constructs a new ConnectionParameters with the same properties as this object but a
515 	 * different access rate.
516 	 * 
517 	 * @param accessRate new access rate
518 	 * @return new ConnectionParameters object
519 	 */
520 	public ConnectionParameters deriveWithAccessRate(int accessRate) {
521 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,
522 				propertySize, dynamicParameters);
523 	}
524 
525 	/**
526 	 * Constructs a new ConnectionParameters with the same properties as this object but a
527 	 * different device group.
528 	 * 
529 	 * @param deviceGroup new device group
530 	 * @return new ConnectionParameters object
531 	 */
532 	public ConnectionParameters deriveWithDeviceGroup(String deviceGroup) {
533 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,
534 				propertySize, dynamicParameters);
535 	}
536 
537 	/**
538 	 * Constructs a new ConnectionParameters with the same properties as this object but a
539 	 * different device name.
540 	 * 
541 	 * @param deviceName new device name
542 	 * @return new ConnectionParameters object
543 	 */
544 	public ConnectionParameters deriveWithDeviceName(String deviceName) {
545 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,
546 				propertySize, dynamicParameters);
547 	}
548 
549 	/**
550 	 * Constructs a new ConnectionParameters with the same properties as this object but a
551 	 * different property name.
552 	 * 
553 	 * @param deviceProperty new property name
554 	 * @return new ConnectionParameters object
555 	 */
556 	public ConnectionParameters deriveWithDeviceProperty(String deviceProperty) {
557 		return new ConnectionParameters(accessProtocol,deviceContext,deviceGroup,deviceName,deviceProperty,accessMode,accessRate,
558 				propertySize, dynamicParameters);
559 	}
560 }