Skip to content

Commit 107d695

Browse files
committed
Support code based configuration; Job framework ready
1 parent fc08104 commit 107d695

62 files changed

Lines changed: 2154 additions & 70 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<groupId>org.actframework</groupId>
2323
<artifactId>act</artifactId>
2424
<packaging>jar</packaging>
25-
<version>0.0.1-SNAPSHOT</version>
25+
<version>0.0.2-SNAPSHOT</version>
2626

2727
<name>ACT Framework</name>
2828
<description>The ACT full stack MVC framework</description>
@@ -162,6 +162,12 @@
162162
<version>1.3.1</version>
163163
</dependency>
164164

165+
<dependency>
166+
<groupId>com.cronutils</groupId>
167+
<artifactId>cron-utils</artifactId>
168+
<version>2.0.0</version>
169+
</dependency>
170+
165171
<dependency>
166172
<groupId>org.osgl</groupId>
167173
<artifactId>osgl-tool</artifactId>

src/main/java/act/app/App.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package act.app;
22

33
import act.Act;
4+
import act.app.event.AppEvent;
5+
import act.app.event.AppEventManager;
46
import act.conf.AppConfLoader;
57
import act.conf.AppConfig;
68
import act.controller.ControllerSourceCodeScanner;
79
import act.controller.bytecode.ControllerByteCodeScanner;
810
import act.di.DependencyInjector;
11+
import act.job.AppJobManager;
12+
import act.job.meta.JobByteCodeScanner;
13+
import act.job.meta.JobSourceCodeScanner;
914
import act.route.RouteTableRouterBuilder;
1015
import act.route.Router;
11-
import act.util.FsChangeDetector;
12-
import act.util.FsEvent;
13-
import act.util.FsEventListener;
1416
import act.util.UploadFileStorageService;
1517
import org.apache.commons.codec.Charsets;
1618
import org.osgl._;
@@ -44,7 +46,9 @@ public enum F {
4446
private AppClassLoader classLoader;
4547
private ProjectLayout layout;
4648
private AppBuilder builder;
49+
private AppEventManager eventManager;
4750
private AppCodeScannerManager scannerManager;
51+
private AppJobManager jobManager;
4852
private AppInterceptorManager interceptorManager;
4953
private DependencyInjector<?> dependencyInjector;
5054
private IStorageService uploadFileStorageService;
@@ -104,17 +108,21 @@ public void restart() {
104108
}
105109

106110
public void refresh() {
111+
Act.viewManager().reload(this);
107112
initServiceResourceManager();
113+
initEventManager();
108114
initInterceptorManager();
109115
loadConfig();
110116
initUploadFileStorageService();
111117
initRouter();
118+
initJobManager();
112119
initScannerManager();
113120
loadActScanners();
114121
loadBuiltInScanners();
115122
initClassLoader();
116123
scanAppCodes();
117124
loadRoutes();
125+
eventManager().emitEvent(AppEvent.START);
118126
}
119127

120128
public AppBuilder builder() {
@@ -141,6 +149,14 @@ public AppCodeScannerManager scannerManager() {
141149
return scannerManager;
142150
}
143151

152+
public AppEventManager eventManager() {
153+
return eventManager;
154+
}
155+
156+
public AppJobManager jobManager() {
157+
return jobManager;
158+
}
159+
144160
public App injector(DependencyInjector<?> dependencyInjector) {
145161
E.NPE(dependencyInjector);
146162
E.illegalStateIf(null != this.dependencyInjector, "Dependency injection factory already set");
@@ -212,6 +228,7 @@ private void loadConfig() {
212228

213229
private void initServiceResourceManager() {
214230
if (null != serviceResourceManager) {
231+
eventManager().emitEvent(AppEvent.STOP);
215232
serviceResourceManager.destroy();
216233
dependencyInjector = null;
217234
}
@@ -226,6 +243,14 @@ private void initRouter() {
226243
router = new Router(this);
227244
}
228245

246+
private void initEventManager() {
247+
eventManager = new AppEventManager(this);
248+
}
249+
250+
private void initJobManager() {
251+
jobManager = new AppJobManager(this);
252+
}
253+
229254
private void initInterceptorManager() {
230255
interceptorManager = new AppInterceptorManager(this);
231256
}
@@ -241,6 +266,8 @@ private void loadActScanners() {
241266
private void loadBuiltInScanners() {
242267
scannerManager.register(new ControllerSourceCodeScanner());
243268
scannerManager.register(new ControllerByteCodeScanner());
269+
scannerManager.register(new JobSourceCodeScanner());
270+
scannerManager.register(new JobByteCodeScanner());
244271
}
245272

246273
private void loadRoutes() {

src/main/java/act/app/AppByteCodeScanner.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import act.util.ByteCodeVisitor;
44

5+
import java.util.Map;
56
import java.util.Set;
67

78
/**
@@ -18,7 +19,7 @@ public interface AppByteCodeScanner extends AppCodeScanner {
1819
* to check if there are dependency class needs to be scanned
1920
* again
2021
*/
21-
Set<String> dependencyClasses();
22+
Map<Class<? extends AppByteCodeScanner>, Set<String>> dependencyClasses();
2223

2324
/**
2425
* Called when scanning for one class finished

src/main/java/act/app/AppByteCodeScannerBase.java

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,51 @@
22

33
import org.osgl.util.C;
44

5+
import java.util.Collection;
6+
import java.util.Map;
57
import java.util.Set;
68

79
/**
810
* Base class for all {@link AppByteCodeScanner} implementations
911
*/
1012
public abstract class AppByteCodeScannerBase extends AppCodeScannerBase implements AppByteCodeScanner {
1113

12-
private Set<String> dependencyClasses;
14+
private Map<Class<? extends AppByteCodeScanner>, Set<String>> dependencyClasses;
1315

1416
protected final void reset() {
15-
dependencyClasses = C.newSet();
17+
dependencyClasses = C.newMap();
1618
}
1719

1820
protected final void addDependencyClass(String className) {
19-
dependencyClasses.add(className);
21+
Set<String> set = dependencyClasses.get(getClass());
22+
if (null == set) {
23+
set = C.newSet();
24+
dependencyClasses.put(getClass(), set);
25+
}
26+
set.add(className);
27+
}
28+
29+
protected final void addDependencyClassToScanner(Class<? extends AppByteCodeScanner> scannerClass, String className) {
30+
Set<String> set = dependencyClasses.get(scannerClass);
31+
if (null == set) {
32+
set = C.newSet();
33+
dependencyClasses.put(scannerClass, set);
34+
}
35+
set.add(className);
36+
}
37+
38+
protected final void addDependencyClassToScanner(Class<? extends AppByteCodeScanner> scannerClass, Collection<String> classNames) {
39+
Set<String> set = dependencyClasses.get(scannerClass);
40+
if (null == set) {
41+
set = C.newSet();
42+
dependencyClasses.put(scannerClass, set);
43+
}
44+
set.addAll(classNames);
2045
}
2146

2247
@Override
23-
public final Set<String> dependencyClasses() {
24-
return C.set(dependencyClasses);
48+
public final Map<Class<? extends AppByteCodeScanner>, Set<String>> dependencyClasses() {
49+
return C.map(dependencyClasses);
2550
}
2651

2752
}

src/main/java/act/app/AppClassLoader.java

Lines changed: 73 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
import act.Act;
44
import act.asm.ClassReader;
55
import act.asm.ClassWriter;
6+
import act.boot.BootstrapClassLoader;
67
import act.controller.meta.ControllerClassMetaInfo;
78
import act.controller.meta.ControllerClassMetaInfoHolder;
89
import act.controller.meta.ControllerClassMetaInfoManager;
9-
import act.util.ByteCodeVisitor;
10-
import act.util.ClassNames;
11-
import act.util.Files;
12-
import act.util.Jars;
10+
import act.job.meta.JobClassMetaInfo;
11+
import act.job.meta.JobClassMetaInfoManager;
12+
import act.util.*;
1313
import org.osgl._;
1414
import org.osgl.exception.NotAppliedException;
1515
import org.osgl.logging.L;
@@ -31,12 +31,13 @@
3131
/**
3232
* The top level class loader to load a specific application classes into JVM
3333
*/
34-
public class AppClassLoader extends ClassLoader implements ControllerClassMetaInfoHolder, AppService<AppClassLoader> {
34+
public class AppClassLoader extends ClassLoader implements ControllerClassMetaInfoHolder, AppService<AppClassLoader>, ActClassLoader {
3535
protected final static Logger logger = L.get(AppClassLoader.class);
3636
private App app;
3737
private Map<String, byte[]> libClsCache = C.newMap();
3838
private boolean destroyed;
3939
protected ControllerClassMetaInfoManager controllerInfo = new ControllerClassMetaInfoManager();
40+
protected JobClassMetaInfoManager jobInfo = new JobClassMetaInfoManager();
4041

4142
public AppClassLoader(App app) {
4243
super(Act.class.getClassLoader());
@@ -62,6 +63,7 @@ public final App app() {
6263
public final void destroy() {
6364
libClsCache.clear();
6465
controllerInfo.destroy();
66+
jobInfo.destroy();
6567
releaseResources();
6668
destroyed = true;
6769
}
@@ -77,14 +79,33 @@ public ControllerClassMetaInfo controllerClassMetaInfo(String controllerClassNam
7779
return controllerInfo.controllerMetaInfo(controllerClassName);
7880
}
7981

80-
public ControllerClassMetaInfoManager controllerClassMetaInfoManager2() {
82+
public ControllerClassMetaInfoManager controllerClassMetaInfoManager() {
8183
return controllerInfo;
8284
}
8385

86+
public JobClassMetaInfo jobClassMetaInfo(String jobClassName) {
87+
return jobInfo.jobMetaInfo(jobClassName);
88+
}
89+
90+
public JobClassMetaInfoManager jobClassMetaInfoManager() {
91+
return jobInfo;
92+
}
93+
8494
public boolean isSourceClass(String className) {
8595
return false;
8696
}
8797

98+
public Class<?> loadedClass(String name) {
99+
Class<?> c = findLoadedClass(name);
100+
if (null == c) {
101+
ClassLoader p = getParent();
102+
if (null != p && (p instanceof ActClassLoader || p instanceof BootstrapClassLoader)) {
103+
return ((ActClassLoader)p).loadedClass(name);
104+
}
105+
}
106+
return c;
107+
}
108+
88109
@Override
89110
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
90111
Class<?> c = findLoadedClass(name);
@@ -138,19 +159,22 @@ protected void scanByteCode(Iterable<String> classes, _.Function<String, byte[]>
138159
cr.accept(theVisitor, 0);
139160
for (AppByteCodeScanner scanner : scanners) {
140161
scanner.scanFinished(className);
141-
Set<String> ss = scanner.dependencyClasses();
162+
Map<Class<? extends AppByteCodeScanner>, Set<String>> ss = scanner.dependencyClasses();
142163
if (ss.isEmpty()) {
143164
logger.debug("no dependencies found for %s by scanner %s", className, scanner);
144165
continue;
145166
}
146-
for (String dependencyClass : ss) {
147-
logger.debug("dependencies[%s] found for %s by scanner %s", dependencyClass, className, scanner);
148-
List<AppByteCodeScanner> l = dependencies.get(dependencyClass);
149-
if (null == l) {
150-
l = C.newList();
151-
dependencies.put(dependencyClass, l);
167+
for (Class<? extends AppByteCodeScanner> scannerClass : ss.keySet()) {
168+
AppByteCodeScanner scannerA = scannerManager.byteCodeScannerByClass(scannerClass);
169+
for (String dependencyClass : ss.get(scannerClass)) {
170+
logger.debug("dependencies[%s] found for %s by scanner %s", dependencyClass, className, scannerA);
171+
List<AppByteCodeScanner> l = dependencies.get(dependencyClass);
172+
if (null == l) {
173+
l = C.newList();
174+
dependencies.put(dependencyClass, l);
175+
}
176+
if (!l.contains(scanner)) l.add(scannerA);
152177
}
153-
if (!l.contains(scanner)) l.add(scanner);
154178
}
155179
}
156180
}
@@ -164,21 +188,26 @@ protected void scanByteCode(Iterable<String> classes, _.Function<String, byte[]>
164188
visitors.add(scanner.byteCodeVisitor());
165189
}
166190
ByteCodeVisitor theVisitor = ByteCodeVisitor.chain(visitors);
167-
ClassReader cr = new ClassReader(libClsCache.get(className));
191+
ClassReader cr = new ClassReader(bytecodeProvider.apply(className));
168192
cr.accept(theVisitor, 0);
169193
for (AppByteCodeScanner scanner : scanners) {
170194
scanner.scanFinished(className);
171-
Set<String> ss = scanner.dependencyClasses();
195+
Map<Class<? extends AppByteCodeScanner>, Set<String>> ss = scanner.dependencyClasses();
172196
if (ss.isEmpty()) {
197+
logger.debug("no dependencies found for %s by scanner %s", className, scanner);
173198
continue;
174199
}
175-
for (String dependencyClass : ss) {
176-
List<AppByteCodeScanner> l = dependencies.get(dependencyClass);
177-
if (null == l) {
178-
l = C.newList();
179-
dependencies.put(dependencyClass, l);
200+
for (Class<? extends AppByteCodeScanner> scannerClass : ss.keySet()) {
201+
AppByteCodeScanner scannerA = scannerManager.byteCodeScannerByClass(scannerClass);
202+
for (String dependencyClass : ss.get(scannerClass)) {
203+
logger.debug("dependencies[%s] found for %s by scanner %s", dependencyClass, className, scannerA);
204+
List<AppByteCodeScanner> l = dependencies.get(dependencyClass);
205+
if (null == l) {
206+
l = C.newList();
207+
dependencies.put(dependencyClass, l);
208+
}
209+
if (!l.contains(scanner)) l.add(scannerA);
180210
}
181-
if (!l.contains(scanner)) l.add(scanner);
182211
}
183212
}
184213
}
@@ -208,9 +237,24 @@ protected void preloadClassFile(File base, File file) {
208237
libClsCache.put(ClassNames.sourceFileNameToClassName(base, file.getAbsolutePath().replace(".class", ".java")), bytes);
209238
}
210239

240+
protected byte[] loadAppClassFromDisk(String name) {
241+
File base = new File(app().layout().target(app().base()), "classes");
242+
if (base.canRead() && base.isDirectory()) {
243+
String path = ClassNames.classNameToClassFileName(name);
244+
File classFile = new File(base, path);
245+
if (classFile.canRead()) {
246+
return IO.readContent(classFile);
247+
}
248+
}
249+
return null;
250+
}
251+
211252
private Class<?> loadAppClass(String name, boolean resolve) {
212253
byte[] bytecode = appBytecode(name);
213-
if (null == bytecode) return null;
254+
if (null == bytecode) {
255+
bytecode = loadAppClassFromDisk(name);
256+
if (null == bytecode) return null;
257+
}
214258
if (!app().config().needEnhancement(name)) {
215259
Class<?> c = super.defineClass(name, bytecode, 0, bytecode.length, DOMAIN);
216260
if (resolve) {
@@ -239,6 +283,7 @@ protected byte[] enhance(String className, byte[] bytecode) {
239283
}
240284

241285
private byte[] asmEnhance(String className, byte[] bytecode) {
286+
if (!enhanceEligible(className)) return bytecode;
242287
_.Var<ClassWriter> cw = _.var(null);
243288
ByteCodeVisitor enhancer = Act.enhancerManager().appEnhancer(app, className, cw);
244289
if (null == enhancer) {
@@ -312,4 +357,9 @@ public boolean test(String s) {
312357
};
313358
static _.Predicate<String> SAFE_CLASS = S.F.endsWith(".class").and(SYS_CLASS_NAME.negate());
314359
}
360+
361+
protected static boolean enhanceEligible(String name) {
362+
boolean sys = name.startsWith("java") || name.startsWith("com.google") || name.startsWith("org.apache") || name.startsWith("org.springframework");
363+
return !sys;
364+
}
315365
}

src/main/java/act/app/AppCodeScannerManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ public C.List<AppByteCodeScanner> byteCodeScanners() {
2929
return C.list(byteCodeScanners);
3030
}
3131

32+
public AppByteCodeScanner byteCodeScannerByClass(Class<? extends AppByteCodeScanner> c) {
33+
for (AppByteCodeScanner scanner : byteCodeScanners) {
34+
if (scanner.getClass() == c) {
35+
return scanner;
36+
}
37+
}
38+
return null;
39+
}
40+
3241
public AppCodeScannerManager register(AppSourceCodeScanner sourceCodeScanner) {
3342
_register(sourceCodeScanner, sourceCodeScanners);
3443
return this;

0 commit comments

Comments
 (0)