forked from actframework/actframework
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEnv.java
More file actions
346 lines (303 loc) · 10.6 KB
/
Env.java
File metadata and controls
346 lines (303 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
package act.sys;
/*-
* #%L
* ACT Framework
* %%
* Copyright (C) 2014 - 2017 ActFramework
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import act.Act;
import org.osgl.util.C;
import org.osgl.util.OS;
import org.osgl.util.S;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.annotation.*;
import java.lang.management.ManagementFactory;
import java.lang.reflect.AnnotatedElement;
/**
* Mark a module should only be loaded in certain environment
*/
public final class Env {
private Env() {}
/**
* Used to mark a dependency injector module that
* should be load only in specified profile.
*
* This annotation shall NOT used along with
* {@link Mode} and {@link Group}
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequireProfile {
/**
* The profile specification
*/
String value();
/**
* If `except` is `true` then the module should be load
* when the current profile is **NOT** the value specified
*/
boolean except() default false;
}
/**
* Used to mark a dependency injector module that
* should be load only in specified profile.
*
* This annotation shall NOT used along with
* {@link Mode} and {@link Group}
*
* This annotation is deprecated. Please use {@link RequireProfile} instead
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Deprecated
public @interface Profile {
/**
* The profile specification
*/
String value();
/**
* If unless is `true` then the module should be load
* unless the current profile is the value specified
*/
boolean unless() default false;
}
/**
* Used to mark a dependency injector module that
* should be load only in specified node group
*
* This annotation shall NOT used along with
* {@link Mode} and {@link RequireProfile}
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequireGroup {
/**
* The node group specification
*/
String value();
/**
* If `except` is `true` then the module should be load
* when the current node group is **NOT** the value specified
*/
boolean except() default false;
}
/**
* Used to mark a dependency injector module that
* should be load only in specified node group
*
* This annotation shall NOT used along with
* {@link Mode} and {@link Profile}
*
* This annotation is deprecated. Please use {@link RequireGroup}
* instead
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Deprecated
public @interface Group {
/**
* The node group specification
*/
String value();
/**
* If unless is `true` then the module should be load
* unless the current node group is the value specified
*/
boolean unless() default false;
}
/**
* Used to mark a dependency injector module
* that should be load only in specified mode
*
* This annotation shall NOT used along with
* {@link RequireProfile} and {@link RequireGroup}
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequireMode {
/**
* The mode specification
*/
Act.Mode value();
/**
* If `except` is `true` then the module should be load
* when the current mode is **NOT** the value specified
*/
boolean except() default false;
}
/**
* Used to mark a dependency injector module
* that should be load only in specified mode
*
* This annotation shall NOT used along with
* {@link RequireProfile} and {@link RequireGroup}
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Mode {
/**
* The mode specification
*/
Act.Mode value();
/**
* If unless is `true` then the module should be load
* unless the current mode is the value specified
*/
boolean unless() default false;
}
public static boolean matches(RequireMode modeTag) {
return modeMatches(modeTag.value(), modeTag.except());
}
/**
* This method is deprecated. Please use {@link #matches(RequireMode)} instead
*/
@Deprecated
public static boolean matches(Mode modeTag) {
return modeMatches(modeTag.value(), modeTag.unless());
}
public static boolean modeMatches(Act.Mode mode) {
return mode == Act.mode();
}
public static boolean modeMatches(Act.Mode mode, boolean unless) {
return unless ^ modeMatches(mode);
}
public static boolean matches(RequireProfile profileTag) {
return profileMatches(profileTag.value(), profileTag.except());
}
/**
* This method is deprecated. Please use {@link #matches(RequireProfile)} instead
*/
@Deprecated
public static boolean matches(Profile profileTag) {
return profileMatches(profileTag.value(), profileTag.unless());
}
public static boolean profileMatches(String profile) {
return S.eq(profile, Act.profile(), S.IGNORECASE);
}
public static boolean profileMatches(String profile, boolean unless) {
return unless ^ profileMatches(profile);
}
public static boolean matches(RequireGroup groupTag) {
return groupMatches(groupTag.value(), groupTag.except());
}
/**
* This method is deprecated. Please use {@link #matches(RequireGroup)} instead
*/
@Deprecated
public static boolean matches(Group groupTag) {
return groupMatches(groupTag.value(), groupTag.unless());
}
public static boolean groupMatches(String group) {
return S.eq(group, Act.nodeGroup(), S.IGNORECASE);
}
public static boolean groupMatches(String group, boolean unless) {
return unless ^ groupMatches(group);
}
private static final C.Set<Class<? extends Annotation>> ENV_ANNOTATION_TYPES = C.set(
Env.Mode.class, Env.Profile.class, Env.Group.class,
Env.RequireProfile.class, Env.RequireGroup.class, Env.RequireMode.class
);
public static boolean isEnvAnnotation(Class<? extends Annotation> type) {
return ENV_ANNOTATION_TYPES.contains(type);
}
/**
* Determine if an {@link AnnotatedElement} has environment annotations and if it has then check
* if all environment annotations matches the current executing environment
* @param annotatedElement an annotated element
* @return `true` if the element does not have environment annotations or all environment annotations matches
*/
public static boolean matches(AnnotatedElement annotatedElement) {
Annotation[] annotations = annotatedElement.getDeclaredAnnotations();
for (Annotation anno : annotations) {
if (anno instanceof RequireProfile) {
RequireProfile profile = (RequireProfile) anno;
if (!matches(profile)) {
return false;
}
} else if (anno instanceof RequireMode) {
RequireMode mode = (RequireMode) anno;
if (!matches(mode)) {
return false;
}
} else if (anno instanceof RequireGroup) {
RequireGroup group = (RequireGroup) anno;
if (!matches(group)) {
return false;
}
} else if (anno instanceof Profile) {
Profile profile = (Profile)anno;
if (!matches(profile)) {
return false;
}
} else if (anno instanceof Group) {
Group group = (Group) anno;
if (!matches(group)) {
return false;
}
} else if (anno instanceof Mode) {
Mode mode = (Mode) anno;
if (!matches(mode)) {
return false;
}
}
}
return true;
}
// See http://stackoverflow.com/questions/534648/how-to-daemonize-a-java-program
public static class PID {
private static String pid = getPid();
private static String getPid() {
OS os = OS.get();
if (os.isUnix()) {
File proc_self = new File("/proc/self");
if(proc_self.exists()) try {
return proc_self.getCanonicalFile().getName();
}
catch(Exception e) {
/// Continue on fall-back
}
File bash = new File("/bin/sh");
if(bash.exists()) {
ProcessBuilder pb = new ProcessBuilder("/bin/sh","-c","echo $PPID");
try {
Process p = pb.start();
BufferedReader rd = new BufferedReader(new InputStreamReader(p.getInputStream()));
return rd.readLine();
}
catch(IOException e) {
return String.valueOf(Thread.currentThread().getId());
}
}
} else {
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
if (null != nameOfRunningVM) {
int p = nameOfRunningVM.indexOf('@');
if (p > -1) {
return nameOfRunningVM.substring(0, p);
}
}
}
// The final resort
return String.valueOf(Thread.currentThread().getId());
}
public static String get() {
return pid;
}
}
}