Use Java annotations to generate js files for front-end calls of constant classes
Annotation is equivalent to a flag. Adding an annotation in the program is equivalent to marking the program. If it is not added, it means there is no mark. Later, the javac compiler, development tools and other programs can use reflection to understand whether there are any tags on your classes and various elements. If you have any tags, you can do the relevant work. The tag can be added to the package, class, field, method, method parameters, and local variables.
1) define the simplest Annotation
public@interfaceMyAnnotation{//......}
2) Add the annotation to a class:
@MyAnnotationpublicclassAnnotationTest{//......}
The constant class annotation is as follows:
Packagecom. gaochao. platform. util; importjava. lang. annotation. elementType; importjava. lang. annotation. retention; importjava. lang. annotation. retentionPolicy; importjava. lang. annotation. target;/*** constant Chinese conversion annotation * @ authorchao. gao * @ date2013-12-20 1:02:02 * @ version1.0.0* // @ Retention (RetentionPolicy. RUNTIME) @ Target (ElementType. FIELD) public @ interfaceConstantsText {/*** data dictionary label. Use * @ authorchao to obtain Chinese meanings. gao * @ date2013-12-20 1:17:19 * @ return */publicStringtermsLable () default;/*** used when the data dictionary does not have the opposite Chinese, manually set * @ authorchao. gao * @ date2013-12-20 1:17:40 * @ return */publicStringtext () default ;}
There are two meta annotations at the top of the annotation, which are annotation annotations. The meaning and usage are as follows:
// Four annotation types are provided in Java, which are used to annotate other annotations, respectively. // @ Retention annotation, indicates the level at which the annotation information (lifecycle) needs to be saved ). Optional RetentionPoicy parameters include: // RetentionPolicy. SOURCE: Stay in the java SOURCE file, and the compiler is discarded. // RetentionPolicy. CLASS: Stay in the class file, but will be discarded by the VM (default) // RetentionPolicy. RUNTIME: the bytecode in the memory. The VM retains the annotation during RUNTIME. Therefore, the annotation information can be read through the reflection mechanism // @ Target meta annotation. The default value is any element, indicates where the annotation is used. Available ElementType parameters include // ElementType. CONSTRUCTOR: CONSTRUCTOR declaration // ElementType. FIELD: member variables, objects, attributes (including enum instances) // ElementType. LOCAL_VARIABLE: local variable declaration // ElementType. METHOD: METHOD declaration // ElementType. PACKAGE: PACKAGE declaration // ElementType. PARAMETER: PARAMETER declaration // ElementType. TYPE: Class, interface (including annotation TYPE), or enum Declaration
// @ Brief ented include the annotation in JavaDoc // @ Inheried allows the subclass to inherit the annotation in the parent class
Apply the annotation in the constant class:
publicclassRelationshipConstants{publicstaticfinalStringSTATUS_SAVED=saved;publicstaticfinalStringSTATUS_FINISHED=finished;publicstaticfinalintHAVE_YES=1;publicstaticfinalintHAVE_NO=0;}
After adding annotations
/*** Scheduler status: reviewed */@ ConstantsText (text = I am a manual reviewer) publicstaticfinalStringPLANSTATUS_AUDITED = audited;/*** scheduler status: voided, search for */@ ConstantsText (termsLable = planStatus) terminated = canceled;/*** plan status: Completed */@ ConstantsText (termsLable = planStatus) finished = finished;
Explanation:
PublicstaticStringgetText (Fieldfield) throwsException {StringfieldValue = field. get (null ). toString (); if (field. isAnnotationPresent (ConstantsText. class) {ConstantsTextct = field. getAnnotation (ConstantsText. class); if (! StringUtils. isBlank (ct. text () {returnct. text ();} if (! StringUtils. isBlank (ct. termsLable () {StringresultStr =; if (map. get (ct. termsLable ())! = Null) {resultStr = map. get (ct. termsLable ()). get (fieldValue);} else {logger. error (not found in data dictionary: termsLable: [+ ct. termsLable () +]!);} If (resultStr! = Null) returnresultStr; else {logger. error (termslable not found in the data dictionary: [+ ct. termsLable () +], termsCode: the value of [+ fieldValue + !);}}} ReturnfieldValue ;}}
Generate js logic:
Using (StringfPath) {StringwebRoot = AppContext. getAppContext (). getWebAppRoot () +/scripts/; fPath = webRoot; StringtempPath = fPath; using = using (); StringfileName =; Map
FileNameMap = newHashMap
(); Try {// get all * Constants. class file Resource [] file = util. getResources (classpath *: com/fx/oa/**/api/define/* Constants. class); StringBufferjsContent = null; for (Resourceresource: file) {logger.info (scanned file: >>>>> + resource. getURI (); jsContent = null; Stringclazz = resource. getURI (). toString (); jsContent = newStringBuffer (); // obtain the full path of the constant class required for reflection, 2 :! /, 6:. classStringclassName = clazz. substring (clazz. lastIndexOf (!) + 2, clazz. length ()-6 ). replace (/,.); fileName = className. substring (0, className. indexOf (. api); // 1 :. fileName = fileName. substring (fileName. lastIndexOf (.) + 1); if (fileName. length ()> 0) & fileNameMap. containsKey (fileName) {jsContent = fileNameMap. get (fileName);} logger.info (constant class scanned: + className); // obtain the top-level var variable name StringvarName = oa. + className. substring (className. lastIndexOf (.) + 1 ). replace (Constants ,). toLowerCase (); jsContent. Append (genContent (className, fileName, varName); if (jsContent. length () = 0) {logger.info (constant class + className + undefined anything, Skip !); Continue;} else {fileNameMap. put (fileName, jsContent) ;}for (Strings: fileNameMap. keySet () {fPath + = s; FileoutDir = newFile (fPath); // output JS file if (! OutDir. exists () {if (! OutDir. mkdir () {thrownewRuntimeException (create directory: + outDir + failed !);}} StringBufferf = fileNameMap. get (s); FilejsFile = newFile (fPath ++ s +. js); logger.info (generate the Js file path (File System): + jsFile. getAbsolutePath (); logger.info (generate Js file path (relative project path): + jsFile. getPath (); BufferedOutputStreambos = newBufferedOutputStream (newFileOutputStream (jsFile); bos. write (f. toString (). getBytes (); bos. close (); fPath = tempPath;} catch (partition tione) {logger. error (e. getMessage (); thrownewRuntimeException (e) ;}@ SuppressWarnings ({rawtypes, unchecked}) handle (StringclassName, StringpackageName, StringvarName) throwsException {Class
Clazz = Class. forName (className); StringBufferjsContent = newStringBuffer (); Field [] fields = clazz. getDeclaredFields (); Map
Map = newHashMap
(); Map
MapText = newHashMap
(); List
List = null; List
ListText = null; StringfieldName = null, pre = null, end = null; if (fields. length = 0) {logger.info (className + NO constants have been defined !); ReturnnewStringBuffer () ;}for (Fieldfield: fields) {fieldName = field. getName (); intfieldIndex = fieldName. indexOf (_); if (fieldIndex =-1) {logger. error (className + field: + fieldName + the name does not comply with the specifications !); ThrownewException (className + field: + fieldName + invalid name !);} Pre = fieldName. substring (0, fieldIndex); end = firstCharToUpper (fieldName. substring (fieldName. indexOf (_) + 1 ). toLowerCase (), _); if (map. containsKey (pre) {list = map. get (pre); list. add (end +-+ field. get (null ). toString (); map. put (pre, list); listText = mapText. get (pre); listText. add (end +-+ getText (field); mapText. put (pre, listText);} else {list = newArrayList
(); List. add (end +-+ field. get (null). toString (); map. put (pre, list); listText = newArrayList
(); ListText. add (end +-+ getText (field); mapText. put (pre, listText) ;}} Stringvalue = null; // process English jsContent. append (varName + = {); for (Stringkey: map. keySet () {jsContent. append (+ key. toLowerCase () +: {); for (inti = 0; I
The generated js file is as follows:
requirements.jsoa.requirements={status:{'saved':'saved','finished':'finished'},have:{'yes':1,'no':0}}
After the js file is introduced,
You can obtain the value by using the module name, Function Identifier, meaning, or function identifier [meaning.
Oa. requirements. status. saved
Saved
Oa. requirements. status ['saved']
Saved
Additional instructions:
Add the annotation above the constant that needs to be converted to Chinese meaning in the constant class:
@ ConstantsText (termsLable = "termsLable" in the data dictionary table), the database data dictionary table must have corresponding records. The obtained records are obtained based on termsLable + termsCode to obtain the following Chinese characters, if not, the original English is used.
@ ConstantsText (text = "Chinese meaning you added ")
The generated js is actually a Map:
Oa. recruitmentText = {have: {yes: 1, no: 0}, status: {saved: saved}, planstatus: {saved: saved, submited: submited, audited: I performed a manual review, // This is the textcanceled used: expired, // This is finished in the data dictionary: finished // This is also in the data dictionary }};
Used in js, similar to the following:
template:function(value){returnoa.recruitmentText.planstatus[value.requirementDeptNames];
This article uses annotation, reflection and other technologies to provide the constant information defined in the Constants file to the front-end js, which reduces the amount of code and makes the front-end text consistent.