1
2
3
4
5 package gboat2.base.core.service;
6
7 import gboat2.base.core.GBoatClassLoader;
8 import gboat2.base.core.annotation.Attach;
9 import gboat2.base.core.annotation.Attachs;
10 import gboat2.base.core.annotation.Modules;
11 import gboat2.base.core.annotation.Operation;
12 import gboat2.base.core.annotation.Operations;
13 import gboat2.base.core.annotation.Preference;
14 import gboat2.base.core.model.Module;
15 import gboat2.base.core.model.ModuleAttach;
16 import gboat2.base.core.model.Opera;
17 import gboat2.base.core.model.PreferenceDefinition;
18 import gboat2.base.bridge.util.BundleUtil;
19
20 import java.lang.reflect.Method;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Vector;
27 import java.util.concurrent.CopyOnWriteArrayList;
28
29 import org.apache.commons.lang3.StringUtils;
30 import org.osgi.framework.Bundle;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34
35
36
37
38
39
40
41 public class ModuleService implements IModuleService {
42
43 private static Logger logger = LoggerFactory.getLogger(ModuleService.class);
44
45 private static final List<Module> moduleList = new CopyOnWriteArrayList<Module>();
46
47 private static List<String> toRegistActionPackages = new LinkedList<String>();
48
49
50 private static Map<String, List<Operation>> operationsInClass = new HashMap<String, List<Operation>>();
51
52
53
54
55
56
57
58
59
60 private static Map<String, List<String>> actionMethod2actionOperaCodesMapping = new HashMap<String, List<String>>();
61
62
63
64
65 private static List<PreferenceDefinition> preferences = new Vector<PreferenceDefinition>();
66
67
68
69
70 private static List<ModuleAttach> moduleAttachList = new Vector<ModuleAttach>();
71
72 public static List<String> getOperationCodesOf(String actionClass, String method) {
73 return actionMethod2actionOperaCodesMapping.get(actionClass + "." + method);
74 }
75
76
77
78
79
80 private static void mountOpera2actionMethod(Opera opera) {
81 String actionMethod = opera.getInvokeAction() + "." + opera.getInvokeMethod();
82 if (actionMethod2actionOperaCodesMapping.containsKey(actionMethod)) {
83 List<String> operas = actionMethod2actionOperaCodesMapping.get(actionMethod);
84 if (!operas.contains(opera.getCode())) {
85 operas.add(opera.getCode());
86 }
87 } else {
88 List<String> operaCodes = new LinkedList<String>();
89 operaCodes.add(opera.getCode());
90 actionMethod2actionOperaCodesMapping.put(actionMethod, operaCodes);
91 }
92 }
93
94 @Override
95 public List<Module> getModuleListByBundleName(String bundleName) {
96 List<Module> moduleList = new ArrayList<Module>();
97 if (!StringUtils.isEmpty(bundleName)) {
98 for (Module module : getModuleList()) {
99 if (bundleName.equals(module.getBundleName()) && !moduleList.contains(module)) {
100 moduleList.add(module);
101 }
102 }
103 }
104 return moduleList;
105 }
106
107 @Override
108 public List<Module> getModules() {
109 return getModuleList();
110 }
111
112 @Override
113 public List<Module> getModules(String queryString) {
114 List<Module> moduleList = new ArrayList<Module>();
115 for (Module module : getModuleList()) {
116 if (judgeModule(queryString, module)) {
117 moduleList.add(module);
118 }
119 }
120 return moduleList;
121 }
122
123 @Override
124 public List<Module> getModuleByBundleAddAction(String bundleName, String actionName) {
125 List<Module> moduleList = new ArrayList<Module>();
126 if (!StringUtils.isEmpty(bundleName) && !StringUtils.isEmpty(actionName)) {
127 for (Module module : getModuleList()) {
128 if (bundleName.equals(module.getBundleName())) {
129 moduleList.add(module);
130 }
131 }
132 }
133 return moduleList;
134 }
135
136 public static Module getModuleForMetadata(String bundleName, String actionName) {
137 if (!StringUtils.isEmpty(bundleName) && !StringUtils.isEmpty(actionName)) {
138 for (Module module : getModuleList()) {
139 if (bundleName.equals(module.getBundleName()) && actionName.equals(module.getClassName())) {
140 return module;
141 }
142 }
143 }
144 return null;
145 }
146
147 @Override
148 public List<Opera> getOperaByBundleAddAction(String bundleName, String actionName) {
149 List<Opera> operaList = new ArrayList<Opera>();
150 Module module = getModuleForMetadata(bundleName, actionName);
151 if (module != null) {
152
153 operaList.addAll(module.getOperas());
154 }
155 return operaList;
156 }
157
158 @Override
159 public List<Opera> getOperaByAction(String actionName) {
160 if (actionName.indexOf(".") != -1) {
161 String packageName = actionName.substring(0, actionName.lastIndexOf("."));
162 Bundle bundle = GBoatClassLoader.getInstance().getBundle(packageName);
163 if (null != bundle) {
164 return getOperaByBundleAddAction(bundle.getSymbolicName(), actionName);
165 }
166 }
167 return null;
168 }
169
170
171
172
173
174
175
176 public static List<Opera> getOperaForMetadata(String bundleName, String actionName) {
177 List<Opera> operaList = new ArrayList<Opera>();
178 Module module = getModuleForMetadata(bundleName, actionName);
179 if (module != null) {
180
181 operaList.addAll(module.getOperas());
182 }
183 return operaList;
184 }
185
186
187
188
189
190
191
192 public static boolean isMethodOperationAnnotationed(Class<?> clazz, Method method, String privilegeMethod) {
193 List<Operation> operations;
194 if (operationsInClass.containsKey(clazz.getName())) {
195 operations = (List<Operation>) operationsInClass.get(clazz.getName());
196 } else {
197 operations = new LinkedList<Operation>();
198
199 Operations operAnnotationClass = (Operations) clazz.getAnnotation(Operations.class);
200 if (null != operAnnotationClass) {
201 Operation[] operas = operAnnotationClass.value();
202 for (Operation opera : operas) {
203 operations.add(opera);
204 }
205 }
206 operationsInClass.put(clazz.getName(), operations);
207 }
208 for (Operation opera : operations) {
209 if ((!StringUtils.isEmpty(opera.invokeMethod()) && opera.invokeMethod().equals(privilegeMethod))
210 || (StringUtils.isEmpty(opera.invokeMethod()) && opera.code().equals(privilegeMethod))) {
211 return true;
212 }
213 }
214
215 return method.isAnnotationPresent(Operations.class) || method.isAnnotationPresent(Operation.class);
216 }
217
218
219 public static void registModule(String pkg) {
220
221 synchronized (toRegistActionPackages) {
222 toRegistActionPackages.add(pkg);
223 }
224 }
225
226 private static List<Module> getModuleList() {
227 synchronized (toRegistActionPackages) {
228 if (toRegistActionPackages.size() > 0) {
229 Bundle bundle;
230 for (String pkg : toRegistActionPackages) {
231 bundle = GBoatClassLoader.getInstance().getBundle(pkg);
232 if (bundle == null) {
233 logger.error("Can't find bundle for package[" + pkg + "]");
234 }
235 List<String> classList = BundleUtil.getClasses(pkg, bundle);
236 List<Class<?>> actionList = getClassesFromBundle(classList, bundle);
237 for (Class<?> actionClass : actionList) {
238
239 processPreferenceAnnotation(actionClass, bundle.getSymbolicName());
240
241 processAttachAnnotation(actionClass);
242
243
244 List<Opera> operas = processOperationAnnotationsOfAction(actionClass);
245
246
247 processModuleAnnotationsOfAction(bundle.getSymbolicName(), actionClass, operas);
248 }
249 }
250 toRegistActionPackages.clear();
251 }
252 }
253 return moduleList;
254 }
255
256
257
258
259
260
261
262
263 private static void processModuleAnnotationsOfAction(String bundle, Class<?> action, List<Opera> operas) {
264
265 gboat2.base.core.annotation.Module m = action.getAnnotation(gboat2.base.core.annotation.Module.class);
266 if (null != m) {
267 Module module = new Module(m, bundle, action, operas);
268 if (!moduleList.contains(module)) {
269 moduleList.add(module);
270 }
271 }
272
273
274 Modules tmp = action.getAnnotation(Modules.class);
275 if (null != tmp) {
276 gboat2.base.core.annotation.Module[] modules = tmp.value();
277 for (gboat2.base.core.annotation.Module mod : modules) {
278 Module module = new Module(mod, bundle, action, operas);
279 if (!moduleList.contains(module)) {
280 moduleList.add(module);
281 }
282 }
283 }
284 }
285
286 public static void unRegistModule(Bundle bundle) {
287 for (Module module : moduleList) {
288 if (bundle.getSymbolicName().equals(module.getBundleName())) {
289 moduleList.remove(module);
290 }
291 }
292 }
293
294
295
296
297
298
299
300 private static boolean isCrossAction(Opera opera) {
301 return !opera.getAction().equals(opera.getInvokeAction());
302 }
303
304
305
306
307
308
309
310
311 private static Opera constructMethodLevelOpera(Operation operation, Method method, Class<?> action) {
312 Opera opera = new Opera(operation, method, action);
313
314
315 mountOpera2actionMethod(opera);
316
317
318 if (isCrossAction(opera)) {
319
320 Opera tmp = new Opera("", operation.code(), action.getClass().getName(), action.getClass().getName(), method.getName(), "");
321 mountOpera2actionMethod(tmp);
322 }
323 return opera;
324 }
325
326
327
328
329
330
331
332 private static Opera constructClassLevelOpera(Operation operation, Class<?> action) {
333 Opera opera = new Opera(operation, action);
334
335 mountOpera2actionMethod(opera);
336 return opera;
337 }
338
339
340
341
342
343
344
345 private static List<Opera> processOperationAnnotationsOfAction(Class<?> action) {
346 List<Opera> operas = new ArrayList<Opera>();
347
348
349 List<Method> methods = getMethodsOfOperationAnnotationed(action);
350 Operations operations;
351 Operation operation;
352 if (null != methods) {
353 for (Method method : methods) {
354 operations = method.getAnnotation(Operations.class);
355 if (null != operations) {
356 Operation[] opers = operations.value();
357 for (Operation tmp : opers) {
358 operas.add(constructMethodLevelOpera(tmp, method, action));
359 }
360 }
361 operation = method.getAnnotation(Operation.class);
362 if (null != operation) {
363 operas.add(constructMethodLevelOpera(operation, method, action));
364 }
365 }
366 }
367
368
369 operations = action.getAnnotation(Operations.class);
370 if (null != operations) {
371 Operation[] opers = operations.value();
372 for (Operation tmp : opers) {
373
374 if (null == getOperaByClassAndcode(operas, tmp.code())) {
375 operas.add(constructClassLevelOpera(tmp, action));
376 }
377 }
378 }
379 operation = action.getAnnotation(Operation.class);
380 if (null != operation) {
381
382 if (null == getOperaByClassAndcode(operas, operation.code())) {
383 operas.add(constructClassLevelOpera(operation, action));
384 }
385 }
386
387 return operas;
388 }
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473 private static List<Method> getMethodsOfOperationAnnotationed(Class<?> clazz) {
474 List<Method> methodList = new ArrayList<Method>();
475 Method[] methodArray = clazz.getMethods();
476 for (Method method : methodArray) {
477 if (method.isAnnotationPresent(Operations.class) || method.isAnnotationPresent(Operation.class)) {
478 methodList.add(method);
479 }
480 }
481 return methodList;
482 }
483
484
485 private boolean judgeModule(String queryStr, Module module) {
486 if (!StringUtils.isEmpty(queryStr)) {
487
488 if (module.getBundleName().indexOf(queryStr) != -1) {
489 return true;
490 }
491 if (module.getClassName().indexOf(queryStr) != -1) {
492 return true;
493 }
494 if (module.getModuleDesc().indexOf(queryStr) != -1) {
495 return true;
496 }
497 if (module.getModuleName().indexOf(queryStr) != -1) {
498 return true;
499 }
500 }
501 return false;
502 }
503
504
505 private static List<Class<?>> getClassesFromBundle(List<String> classNames, Bundle bundle) {
506 List<Class<?>> classes = new ArrayList<Class<?>>();
507 for (String className : classNames) {
508 try {
509 Class<?> clazz = bundle.loadClass(className);
510 if (null != clazz) {
511 classes.add(clazz);
512 }
513 } catch (ClassNotFoundException e) {
514 e.printStackTrace();
515 }
516 }
517 return classes;
518 }
519
520
521
522
523
524
525
526 private static Opera getOperaByClassAndcode(List<Opera> opera, String operaCode) {
527 if (!StringUtils.isEmpty(operaCode)) {
528 for (Opera tempOpera : opera) {
529 if (operaCode.equals(tempOpera.getCode())) {
530 return tempOpera;
531 }
532 }
533 }
534 return null;
535 }
536
537
538
539
540
541 @Override
542 public List<PreferenceDefinition> getPreferences() {
543 return preferences;
544 }
545
546 @Override
547 public List<ModuleAttach> getModuleAttachList() {
548 return moduleAttachList;
549 }
550
551
552 private static void processPreferenceAnnotation(Class<?> actionClass, String bundle) {
553 Preference pre = actionClass.getAnnotation(Preference.class);
554 PreferenceDefinition preDef;
555 if (null != pre) {
556 preDef = new PreferenceDefinition();
557 preDef.setBundle(bundle);
558 preDef.setActionClass(actionClass.getName());
559 preDef.setFullname(pre.value());
560 preferences.add(preDef);
561 }
562
563 Method[] methods = actionClass.getMethods();
564 if (null != methods) {
565 for (Method method : methods) {
566 pre = method.getAnnotation(Preference.class);
567 if (null != pre) {
568 preDef = new PreferenceDefinition();
569 preDef.setBundle(bundle);
570 preDef.setActionClass(actionClass.getName());
571 preDef.setFullname(pre.value());
572 preDef.setMethod(method.getName());
573 preferences.add(preDef);
574 }
575 }
576 }
577 }
578
579
580 private static void processAttachAnnotation(Class<?> actionClass) {
581
582 ModuleAttach moduleAttach;
583
584 Attach attach = actionClass.getAnnotation(Attach.class);
585
586 if (null != attach) {
587 moduleAttach = new ModuleAttach();
588 if (StringUtils.isEmpty(attach.targetName())) {
589 gboat2.base.core.annotation.Module module = actionClass.getAnnotation(gboat2.base.core.annotation.Module.class);
590 if (null != module) {
591 moduleAttach.setModuleName(module.name());
592 }
593 } else {
594 moduleAttach.setModuleName(attach.targetName());
595 }
596 moduleAttach.setAttachCode(attach.code());
597 moduleAttachList.add(moduleAttach);
598 }
599
600
601 Attachs attachs = actionClass.getAnnotation(Attachs.class);
602 if (null != attachs) {
603 Attach[] attachArray = attachs.value();
604 for (Attach att : attachArray) {
605 moduleAttach = new ModuleAttach();
606 moduleAttach.setAttachCode(att.targetCode());
607 moduleAttach.setModuleName(att.targetName());
608 if (!moduleAttachList.contains(moduleAttach)) {
609 moduleAttachList.add(moduleAttach);
610 }
611 }
612 }
613
614 }
615
616 }