1
2
3
4
5 package org.epics.pvmanager.jca;
6
7 import gov.aps.jca.CAException;
8 import gov.aps.jca.Context;
9 import gov.aps.jca.JCALibrary;
10 import gov.aps.jca.Monitor;
11 import gov.aps.jca.jni.JNIContext;
12 import java.lang.reflect.InvocationTargetException;
13 import java.lang.reflect.Method;
14 import java.security.AccessController;
15 import java.security.PrivilegedAction;
16 import java.util.logging.Level;
17 import java.util.logging.Logger;
18
19
20
21
22
23
24
25
26
27 public class JCADataSourceBuilder {
28 private static final Logger log = Logger.getLogger(JCADataSource.class.getName());
29
30 Context jcaContext;
31 int monitorMask = Monitor.VALUE | Monitor.ALARM;
32 JCATypeSupport typeSupport;
33 boolean dbePropertySupported = false;
34 Boolean varArraySupported;
35 boolean rtypValueOnly = false;
36 boolean honorZeroPrecision = true;
37
38
39
40
41
42
43
44
45
46 public JCADataSourceBuilder jcaContextClass(String className) {
47 if (jcaContext != null) {
48 throw new IllegalStateException("You should call either jcaContextClass or jcaContext once.");
49 }
50 this.jcaContext = createContext(className);
51 return this;
52 }
53
54
55
56
57
58
59
60
61
62
63
64 public JCADataSourceBuilder jcaContext(Context jcaContext) {
65 if (jcaContext == null) {
66 throw new IllegalStateException("You should call once either jcaContextClass or jcaContext.");
67 }
68 this.jcaContext = jcaContext;
69 return this;
70 }
71
72
73
74
75
76
77
78
79
80
81 public JCADataSourceBuilder monitorMask(int monitorMask) {
82 this.monitorMask = monitorMask;
83 return this;
84 }
85
86
87
88
89
90
91
92
93
94 public JCADataSourceBuilder typeSupport(JCATypeSupport typeSupport) {
95 this.typeSupport = typeSupport;
96 return this;
97 }
98
99
100
101
102
103
104
105
106
107
108 public JCADataSourceBuilder dbePropertySupported(boolean dbePropertySupported) {
109 this.dbePropertySupported = dbePropertySupported;
110 return this;
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public JCADataSourceBuilder varArraySupported(boolean varArraySupported) {
126 this.varArraySupported = varArraySupported;
127 return this;
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141 public JCADataSourceBuilder rtypValueOnly(boolean rtypValueOnly) {
142 this.rtypValueOnly = rtypValueOnly;
143 return this;
144 }
145
146
147
148
149
150
151
152
153
154
155
156 public JCADataSourceBuilder honorZeroPrecision(boolean honorZeroPrecision) {
157 this.honorZeroPrecision = honorZeroPrecision;
158 return this;
159 }
160
161
162
163
164
165
166 public JCADataSource build() {
167 return new JCADataSource(this);
168 }
169
170
171
172
173
174
175
176
177 static boolean isVarArraySupported(Context context) {
178 try {
179 Class cajClazz = Class.forName("com.cosylab.epics.caj.CAJContext");
180 if (cajClazz.isInstance(context)) {
181 return !(context.getVersion().getMajorVersion() <= 1 && context.getVersion().getMinorVersion() <= 1 && context.getVersion().getMaintenanceVersion() <=9);
182 }
183 } catch (ClassNotFoundException ex) {
184
185 }
186
187 if (context instanceof JNIContext) {
188 try {
189 Class<?> jniClazz = Class.forName("gov.aps.jca.jni.JNI");
190 final Method method = jniClazz.getDeclaredMethod("_ca_getRevision", new Class<?>[0]);
191
192 AccessController.doPrivileged(new PrivilegedAction<Object>() {
193
194 @Override
195 public Object run() {
196 method.setAccessible(true);
197 return null;
198 }
199
200 });
201 Integer integer = (Integer) method.invoke(null, new Object[0]);
202 return (integer >= 13);
203 } catch (Exception ex) {
204 log.log(Level.SEVERE, "Couldn't detect varArraySupported", ex);
205 }
206 }
207
208 return true;
209 }
210
211
212
213
214
215
216
217 static Context createContext(String className) {
218 try {
219 JCALibrary jca = JCALibrary.getInstance();
220 return jca.createContext(className);
221 } catch (CAException ex) {
222 log.log(Level.SEVERE, "JCA context creation failed", ex);
223 throw new RuntimeException("JCA context creation failed", ex);
224 }
225 }
226 }