Browse Source

test

tests
roo00 7 years ago
parent
commit
e4714fbd9b
100 changed files with 9400 additions and 0 deletions
  1. 79 0
      o2server/x_base_core_project/.classpath
  2. 6 0
      o2server/x_base_core_project/.idea/ant.xml
  3. 9 0
      o2server/x_base_core_project/.idea/misc.xml
  4. 9 0
      o2server/x_base_core_project/.idea/modules.xml
  5. 7 0
      o2server/x_base_core_project/.idea/vcs.xml
  6. 313 0
      o2server/x_base_core_project/.idea/workspace.xml
  7. 12 0
      o2server/x_base_core_project/.settings/org.eclipse.jdt.core.prefs
  8. 1101 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/EntityManagerContainer.java
  9. 132 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/EntityManagerContainerBasic.java
  10. 32 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/FactorDistributionPolicy.java
  11. 22 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/FieldType.java
  12. 5 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/LogLevel.java
  13. 55 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/PersistChecker.java
  14. 15 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/RemoveChecker.java
  15. 13 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/AbstractChecker.java
  16. 50 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/BooleanValueListPersistChecker.java
  17. 32 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/BooleanValuePersistChecker.java
  18. 32 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/ByteValueArrayPersistChecker.java
  19. 82 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/DateValueListPersistChecker.java
  20. 60 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/DateValuePersistChecker.java
  21. 81 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/DoubleValueListPersistChecker.java
  22. 58 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/DoubleValuePersistChecker.java
  23. 79 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/FloatValueListPersistChecker.java
  24. 58 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/FloatValuePersistChecker.java
  25. 80 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/IntegerValueListPersistChecker.java
  26. 58 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/IntegerValuePersistChecker.java
  27. 79 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/LongValueListPersistChecker.java
  28. 58 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/LongValuePersistChecker.java
  29. 255 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/StringValueListPersistChecker.java
  30. 121 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/StringValueListRemoveChecker.java
  31. 202 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/StringValuePersistChecker.java
  32. 114 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/StringValueRemoveChecker.java
  33. 129 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/factory/EntityManagerContainerFactory.java
  34. 182 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/factory/SliceEntityManagerContainerFactory.java
  35. 318 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/factory/SlicePropertiesBuilder.java
  36. 25 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/AbstractPersistenceProperties.java
  37. 343 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/JpaObject.java
  38. 24 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/JpaObject_.java
  39. 31 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/SliceJpaObject.java
  40. 16 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/SliceJpaObject_.java
  41. 14 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/Storage.java
  42. 301 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageObject.java
  43. 13 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageObject_.java
  44. 6 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageProtocol.java
  45. 6 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageType.java
  46. 38 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CheckPersist.java
  47. 5 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CheckPersistType.java
  48. 20 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CheckRemove.java
  49. 5 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CheckRemoveType.java
  50. 24 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CitationExist.java
  51. 22 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CitationNotExist.java
  52. 18 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/ContainerEntity.java
  53. 9 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/Equal.java
  54. 14 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/Flag.java
  55. 16 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/IdReference.java
  56. 9 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/NotEqual.java
  57. 14 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/RestrictFlag.java
  58. 378 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/DataItem.java
  59. 350 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/DataItemConverter.java
  60. 8 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/ItemCategory.java
  61. 8 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/ItemPrimitiveType.java
  62. 8 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/ItemStringValueType.java
  63. 8 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/ItemType.java
  64. 109 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/EnhancePersistenceXmlWriter.java
  65. 42 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/EntityManagerContainerTools.java
  66. 135 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/JpaObjectTools.java
  67. 125 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/PersistenceXmlWriter.java
  68. 107 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/SqlWriter.java
  69. 8 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/type/GenderType.java
  70. 124 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/openjpa/jdbc/sql/DMDictionary.java
  71. 13 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/AbstractContext.java
  72. 120 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Application.java
  73. 218 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Applications.java
  74. 148 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/AssembleA.java
  75. 126 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/AssembleC.java
  76. 126 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/AssembleM.java
  77. 22 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Compilable.java
  78. 48 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Compile.java
  79. 125 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/CompileA.java
  80. 116 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/CompileC.java
  81. 116 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/CompileM.java
  82. 29 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Compile_x_base_core_project.java
  83. 325 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Context.java
  84. 5 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/CoreA.java
  85. 5 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/CoreC.java
  86. 5 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/CoreM.java
  87. 12 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Deployable.java
  88. 11 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Packages.java
  89. 169 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/ServiceA.java
  90. 169 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/ServiceC.java
  91. 169 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/ServiceM.java
  92. 736 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/Describe.java
  93. 18 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/FieldDescribe.java
  94. 14 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/JaxrsDescribe.java
  95. 22 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/JaxrsMethodDescribe.java
  96. 18 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/JaxrsParameterDescribe.java
  97. 34 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/bean/NameIdPair.java
  98. 66 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/bean/NameValueCountPair.java
  99. 40 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/bean/NameValuePair.java
  100. 54 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/bean/PropertyObject.java

+ 79 - 0
o2server/x_base_core_project/.classpath

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="src" path="src/test/java"/>
+	<classpathentry kind="src" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
+		<attributes>
+			<attribute name="module" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/lang3/commons-lang3-3.4.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/collections4/commons-collections4-4.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/beanutils/commons-beanutils-1.8.3.jar" sourcepath="D:/O2/code/lib/apache/commons/beanutils/commons-beanutils-1.8.3-sources.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/google/gson/gson-2.8.5.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/io/commons-io-2.6.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/codec/commons-codec-1.8.jar" sourcepath="D:/O2/code/lib/apache/commons/codec/commons-codec-1.8-sources.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/ehcache/ehcache-2.10.3.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/ant/ant.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/ant/ant-launcher.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/tomcat/catalina.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/tomcat/catalina-ant.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/tomcat/tomcat-util.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/cargo/cargo-core-uberjar-1.5.0.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/sourceforge/dom4j/dom4j-1.6.1.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/ibm/informix/ifxjdbc.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/ibm/informix/ifxjdbcx.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/mysql/mysql-connector-java-5.1.36-bin.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/postgresql/postgresql-9.4-1205.jdbc42.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/eclipse/jetty/jetty-all-9.3.17.RC0-uber.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/github/jcl/jcl-core-2.7.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/slf4j/slf4j-api-1.7.25.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/vfs/commons-vfs2-2.1.jar" sourcepath="D:/OpenSource/commons-vfs2"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/poi/curvesapi-1.05.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/poi/xmlbeans-3.0.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/h2/h2-1.4.193.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jpinyin/jpinyin-1.1.8.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/ibm/db2/db2jcc_license_cu-10.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/ibm/db2/db2jcc4-10.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/oracle/ojdbc14_g-10.2.0.4.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/openjpa/openjpa-3.0.0-SNAPSHOT.jar" sourcepath="D:/OpenSource/openjpa"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/fileupload/commons-fileupload-1.3.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/net/commons-net-3.6.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/hk2-api-2.5.0-b03.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/hk2-locator-2.5.0-b03.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/hk2-utils-2.5.0-b03.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/jersey-media-multipart-2.25.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/openjpa/commons-collections-3.2.2.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/github/fast-classpath-scanner/fast-classpath-scanner-2.4.5.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/logging/commons-logging-1.2.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/commons/logging/commons-logging-1.2-javadoc.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/jersey-server-2.25.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/jersey-client-2.25.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/jersey-common-2.25.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/jersey-container-servlet-2.25.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/jersey-container-servlet-core-2.25.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/jersey/jersey-guava-2.25.1.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/alibaba/druid/druid-1.1.8.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/quartz/quartz-2.3.0.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/javax/javaee-api-7.0.jar" sourcepath="D:/OpenSource/openjpa"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/poi/poi-3.17.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/poi/poi-examples-3.17.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/poi/poi-excelant-3.17.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/poi/poi-ooxml-3.17.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/poi/poi-scratchpad-3.17.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/tess4j/tess4j-3.4.8.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/tess4j/jna-4.1.0.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/tess4j/jul-to-slf4j-1.7.25.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/pdfbox/fontbox-2.0.11.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/pdfbox/jempbox-1.8.15.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/pdfbox/pdfbox-2.0.11.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/pdfbox/pdfbox-tools-2.0.11.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/pdfbox/preflight-2.0.11.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/pdfbox/xmpbox-2.0.11.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/tess4j/lept4j-1.6.4.jar"/>
+	<classpathentry kind="lib" path="D:/O2/code/lib/apache/poi/ooxml-schemas-1.4.jar"/>
+	<classpathentry kind="output" path="classes"/>
+</classpath>

+ 6 - 0
o2server/x_base_core_project/.idea/ant.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AntConfiguration">
+    <buildFile url="file://$PROJECT_DIR$/x_base_core_project_build.xml" />
+  </component>
+</project>

+ 9 - 0
o2server/x_base_core_project/.idea/misc.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+  <component name="SvnBranchConfigurationManager">
+    <option name="mySupportsUserInfoFilter" value="true" />
+  </component>
+</project>

+ 9 - 0
o2server/x_base_core_project/.idea/modules.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/src/main/main.iml" filepath="$PROJECT_DIR$/src/main/main.iml" />
+      <module fileurl="file://$PROJECT_DIR$/src/test/test.iml" filepath="$PROJECT_DIR$/src/test/test.iml" />
+    </modules>
+  </component>
+</project>

+ 7 - 0
o2server/x_base_core_project/.idea/vcs.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="svn" />
+    <mapping directory="" vcs="svn" />
+  </component>
+</project>

+ 313 - 0
o2server/x_base_core_project/.idea/workspace.xml

@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ChangeListManager">
+    <list default="true" readonly="true" id="009cb93f-8281-44fb-bc75-63df0379d743" name="Default" comment="" />
+    <ignored path="$PROJECT_DIR$/out/" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="TRACKING_ENABLED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="FileEditorManager">
+    <leaf>
+      <file leaf-file-name="x_base_core_project_build.xml" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/x_base_core_project_build.xml">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="399">
+              <caret line="21" column="10" lean-forward="true" selection-start-line="21" selection-start-column="10" selection-end-line="21" selection-end-column="10" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="JsonElementConvertToWrapInException.java" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/main/java/com/x/base/core/exception/JsonElementConvertToWrapInException.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="190">
+              <caret line="10" column="0" lean-forward="true" selection-start-line="10" selection-start-column="0" selection-end-line="10" selection-end-column="0" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="RunningException.java" pinned="false" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/src/main/java/com/x/base/core/exception/RunningException.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="76">
+              <caret line="4" column="13" lean-forward="false" selection-start-line="4" selection-start-column="13" selection-end-line="4" selection-end-column="13" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+    </leaf>
+  </component>
+  <component name="GradleLocalSettings">
+    <option name="externalProjectsViewState">
+      <projects_view />
+    </option>
+  </component>
+  <component name="ProjectFrameBounds" extendedState="6">
+    <option name="x" value="293" />
+    <option name="y" value="40" />
+    <option name="width" value="1400" />
+    <option name="height" value="1000" />
+  </component>
+  <component name="ProjectView">
+    <navigator currentView="ProjectPane" proportions="" version="1">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+      <manualOrder />
+      <foldersAlwaysOnTop value="true" />
+    </navigator>
+    <panes>
+      <pane id="PackagesPane" />
+      <pane id="AndroidView" />
+      <pane id="Scope" />
+      <pane id="ProjectPane">
+        <subPane>
+          <expand>
+            <path>
+              <item name="x_base_core_project" type="b2602c69:ProjectViewProjectNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="x_base_core_project" type="b2602c69:ProjectViewProjectNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="java" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="x_base_core_project" type="b2602c69:ProjectViewProjectNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="java" type="462c0819:PsiDirectoryNode" />
+              <item name="core" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="x_base_core_project" type="b2602c69:ProjectViewProjectNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="java" type="462c0819:PsiDirectoryNode" />
+              <item name="core" type="462c0819:PsiDirectoryNode" />
+              <item name="exception" type="462c0819:PsiDirectoryNode" />
+            </path>
+          </expand>
+          <select />
+        </subPane>
+      </pane>
+      <pane id="Scratches" />
+    </panes>
+  </component>
+  <component name="RunDashboard">
+    <option name="ruleStates">
+      <list>
+        <RuleState>
+          <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+        </RuleState>
+        <RuleState>
+          <option name="name" value="StatusDashboardGroupingRule" />
+        </RuleState>
+      </list>
+    </option>
+  </component>
+  <component name="RunManager">
+    <configuration default="true" type="Applet" factoryName="Applet">
+      <option name="HTML_USED" value="false" />
+      <option name="WIDTH" value="400" />
+      <option name="HEIGHT" value="300" />
+      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+      <module />
+    </configuration>
+    <configuration default="true" type="Application" factoryName="Application">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="VM_PARAMETERS" />
+      <option name="PROGRAM_PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <module name="" />
+      <envs />
+    </configuration>
+    <configuration default="true" type="JUnit" factoryName="JUnit">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="TEST_OBJECT" value="class" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="singleModule" />
+      </option>
+      <envs />
+      <patterns />
+    </configuration>
+    <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
+      <module name="" />
+      <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
+      <option name="PROGRAM_PARAMETERS" />
+      <predefined_log_file id="idea.log" enabled="true" />
+    </configuration>
+    <configuration default="true" type="Remote" factoryName="Remote">
+      <option name="USE_SOCKET_TRANSPORT" value="true" />
+      <option name="SERVER_MODE" value="false" />
+      <option name="SHMEM_ADDRESS" value="javadebug" />
+      <option name="HOST" value="localhost" />
+      <option name="PORT" value="5005" />
+    </configuration>
+    <configuration default="true" type="TestNG" factoryName="TestNG">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="SUITE_NAME" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="GROUP_NAME" />
+      <option name="TEST_OBJECT" value="CLASS" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
+      <option name="OUTPUT_DIRECTORY" />
+      <option name="ANNOTATION_TYPE" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="singleModule" />
+      </option>
+      <option name="USE_DEFAULT_REPORTERS" value="false" />
+      <option name="PROPERTIES_FILE" />
+      <envs />
+      <properties />
+      <listeners />
+    </configuration>
+  </component>
+  <component name="ShelveChangesManager" show_recycled="false">
+    <option name="remove_strategy" value="false" />
+  </component>
+  <component name="SvnConfiguration" cleanupOnStartRun="true">
+    <configuration>C:\Users\Rui\AppData\Roaming\Subversion</configuration>
+    <supportedVersion>125</supportedVersion>
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="009cb93f-8281-44fb-bc75-63df0379d743" name="Default" comment="" />
+      <created>1506502721093</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1506502721093</updated>
+    </task>
+    <servers />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="58" y="-8" width="1870" height="1096" extended-state="6" />
+    <layout>
+      <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Palette&#9;" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Image Layers" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Capture Tool" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.18662351" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.24973032" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Theme Preview" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+    </layout>
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager />
+    <watches-manager />
+  </component>
+  <component name="antWorkspaceConfiguration">
+    <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
+    <option name="FILTER_TARGETS" value="false" />
+    <buildFile url="file://$PROJECT_DIR$/x_base_core_project_build.xml">
+      <expanded value="true" />
+    </buildFile>
+  </component>
+  <component name="editorHistoryManager">
+    <entry file="file://$PROJECT_DIR$/x_base_core_project_build.xml">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="399">
+          <caret line="21" column="10" lean-forward="true" selection-start-line="21" selection-start-column="10" selection-end-line="21" selection-end-column="10" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/main/java/com/x/base/core/exception/JsonElementConvertToWrapInException.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="190">
+          <caret line="10" column="0" lean-forward="true" selection-start-line="10" selection-start-column="0" selection-end-line="10" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/main/java/com/x/base/core/Crypto.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="76">
+          <caret line="17" column="13" lean-forward="false" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/main/java/com/x/base/core/exception/RunningException.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="76">
+          <caret line="4" column="13" lean-forward="false" selection-start-line="4" selection-start-column="13" selection-end-line="4" selection-end-column="13" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+  </component>
+  <component name="masterDetails">
+    <states>
+      <state key="ProjectJDKs.UI">
+        <settings>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+    </states>
+  </component>
+</project>

+ 12 - 0
o2server/x_base_core_project/.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8

+ 1101 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/EntityManagerContainer.java

@@ -0,0 +1,1101 @@
+package com.x.base.core.container;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Objects;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Tuple;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Selection;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.collections4.list.TreeList;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.entity.annotation.CheckRemove;
+import com.x.base.core.entity.annotation.CheckRemoveType;
+import com.x.base.core.entity.tools.JpaObjectTools;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.exception.ExceptionWhen;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.tools.StringTools;
+
+public class EntityManagerContainer extends EntityManagerContainerBasic {
+
+	public EntityManagerContainer(EntityManagerContainerFactory entityManagerContainerFactory) {
+		super(entityManagerContainerFactory);
+	}
+
+	public void persist(JpaObject o) throws Exception {
+		this.get(o.getClass()).persist(o);
+	}
+
+	public void persist(JpaObject o, CheckPersistType type) throws Exception {
+		if (!type.equals(CheckPersistType.none)) {
+			check(o, type);
+		}
+		this.get(o.getClass()).persist(o);
+	}
+
+	public void remove(JpaObject o) throws Exception {
+		this.get(o.getClass()).remove(o);
+	}
+
+	public void remove(JpaObject o, CheckRemoveType type) throws Exception {
+		if (!type.equals(CheckRemoveType.none)) {
+			check(o, type);
+		}
+		this.get(o.getClass()).remove(o);
+	}
+
+	@SuppressWarnings("unchecked")
+	public void check(JpaObject jpa, CheckPersistType checkPersistType) throws Exception {
+		/** 运行方法进行字段处理 */
+		for (Entry<Field, CheckPersist> entry : entityManagerContainerFactory.getCheckPersistFields(jpa.getClass())
+				.entrySet()) {
+			Field field = entry.getKey();
+			CheckPersist checkPersist = entry.getValue();
+			FieldType fieldType = this.getFieldType(entry.getKey());
+			// Object object = jpa.get(field.getName());
+			Object object = FieldUtils.readField(field, jpa, true);
+			switch (fieldType) {
+			case stringValue:
+				this.persistChecker.stringValue.check(field, null == object ? null : Objects.toString(object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case stringValueList:
+				this.persistChecker.stringValueList.check(field, null == object ? null : (List<String>) object, jpa,
+						checkPersist, checkPersistType);
+				break;
+			case dateValue:
+				this.persistChecker.dateValue.check(field, (null == object ? null : (Date) object), jpa, checkPersist,
+						checkPersistType);
+				break;
+			case dateValueList:
+				this.persistChecker.dateValueList.check(field, (null == object ? null : (List<Date>) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case booleanValue:
+				this.persistChecker.booleanValue.check(field, (null == object ? null : (Boolean) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case booleanValueList:
+				this.persistChecker.booleanValueList.check(field, (null == object ? null : (List<Boolean>) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case integerValue:
+				this.persistChecker.integerValue.check(field, (null == object ? null : (Integer) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case integerValueList:
+				this.persistChecker.integerValueList.check(field, (null == object ? null : (List<Integer>) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case doubleValue:
+				this.persistChecker.doubleValue.check(field, (null == object ? null : (Double) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case doubleValueList:
+				this.persistChecker.doubleValueList.check(field, (null == object ? null : (List<Double>) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case longValue:
+				this.persistChecker.longValue.check(field, (null == object ? null : (Long) object), jpa, checkPersist,
+						checkPersistType);
+				break;
+			case longValueList:
+				this.persistChecker.longValueList.check(field, (null == object ? null : (List<Long>) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case floatValue:
+				this.persistChecker.floatValue.check(field, (null == object ? null : (Float) object), jpa, checkPersist,
+						checkPersistType);
+				break;
+			case floatValueList:
+				this.persistChecker.floatValueList.check(field, (null == object ? null : (List<Float>) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case byteValueArray:
+				this.persistChecker.byteValueArray.check(field, (null == object ? null : (byte[]) object), jpa,
+						checkPersist, checkPersistType);
+				break;
+			case enumValue:
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	public void check(JpaObject jpa, CheckRemoveType checkRemoveType) throws Exception {
+		for (Entry<Field, CheckRemove> entry : entityManagerContainerFactory.getCheckRemoveFields(jpa.getClass())
+				.entrySet()) {
+			Field field = entry.getKey();
+			CheckRemove checkRemove = entry.getValue();
+			FieldType fieldType = this.getFieldType(entry.getKey());
+			// Object object = jpa.get(field.getName());
+			Object object = FieldUtils.readField(field, jpa, true);
+			switch (fieldType) {
+			case stringValue:
+				this.removeChecker.stringValue.check(field, null == object ? null : Objects.toString(object), jpa,
+						checkRemove, checkRemoveType);
+				break;
+			case stringValueList:
+				this.removeChecker.stringValueList.check(field, null == object ? null : (List<String>) object, jpa,
+						checkRemove, checkRemoveType);
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	/**
+	 * 判断id在实体类中是否可用
+	 * 
+	 * @param id
+	 * @param cls
+	 * @return
+	 * @throws Exception
+	 */
+	public <T extends JpaObject> boolean idle(String id, Class<T> cls) throws Exception {
+		T t = this.fetch(id, cls, new ArrayList<String>());
+		if (t == null) {
+			return true;
+		}
+		return false;
+	}
+
+	public <T extends JpaObject> T find(String id, Class<T> cls) throws Exception {
+		return this.find(id, cls, ExceptionWhen.none, false);
+	}
+
+	public <T extends JpaObject> T find(String id, Class<T> cls, ExceptionWhen exceptionWhen) throws Exception {
+		return this.find(id, cls, exceptionWhen, false);
+	}
+
+	public <T extends JpaObject> T find(String id, Class<T> cls, ExceptionWhen exceptionWhen, boolean startTransaction)
+			throws Exception {
+		EntityManager em = startTransaction ? this.beginTransaction(cls) : this.get(cls);
+		T t = null;
+		/* 判断字段长度在定义范围之内否则db2会报错 */
+		if (StringUtils.isNotEmpty(id) && JpaObjectTools.withinDefinedLength(id, cls, JpaObject.id_FIELDNAME)) {
+			t = em.find(cls, id);
+		}
+		switch (exceptionWhen) {
+		case not_found:
+			if (null == t) {
+				throw new Exception("can not find entity id: " + id + ", class: " + cls.getCanonicalName() + ".");
+			}
+			break;
+		case found:
+			if (null != t) {
+				throw new Exception("entity already existed, id: " + id + ", class: " + cls.getCanonicalName() + ".");
+			}
+			break;
+		default:
+			break;
+		}
+		return t;
+	}
+
+	public <T extends JpaObject> T flag(String flag, Class<T> cls) throws Exception {
+		return this.flag(flag, cls, this.entityManagerContainerFactory.getFlagFields(cls));
+	}
+
+	private <T extends JpaObject> T flag(String flag, Class<T> cls, List<Field> fields) throws Exception {
+		EntityManager em = this.get(cls);
+		if (StringUtils.isEmpty(flag) || ListTools.isEmpty(fields)) {
+			return null;
+		}
+		T t = null;
+		out: for (Field field : fields) {
+			if (!JpaObjectTools.withinDefinedLength(flag, cls, field)) {
+				continue;
+			}
+			CriteriaBuilder cb = em.getCriteriaBuilder();
+			CriteriaQuery<T> cq = cb.createQuery(cls);
+			Root<T> root = cq.from(cls);
+			Predicate p = cb.equal(root.get(field.getName()), flag);
+			List<T> list = em.createQuery(cq.select(root).where(p).distinct(true)).setMaxResults(2).getResultList();
+			switch (list.size()) {
+			case 0:
+				break;
+			case 1:
+				t = list.get(0);
+				break out;
+			case 2:
+				throw new Exception("flag get multiple entity flag:" + flag + ", class:" + cls.getName()
+						+ ", attribute:" + field.getName() + ".");
+			}
+		}
+		return t;
+	}
+
+	public <T extends JpaObject> List<T> flag(List<String> FLAGS, Class<T> cls) throws Exception {
+		return this.flag(FLAGS, cls, this.entityManagerContainerFactory.getFlagFields(cls));
+	}
+
+	private <T extends JpaObject> List<T> flag(List<String> FLAGS, Class<T> cls, List<Field> fields) throws Exception {
+		if (ListTools.isEmpty(fields)) {
+			throw new Exception("attributes can not be empty.");
+		}
+		List<T> list = new ArrayList<>();
+		if (ListTools.isEmpty(FLAGS)) {
+			return list;
+		}
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		Predicate[] ps = new Predicate[fields.size()];
+		for (int i = 0; i < fields.size(); i++) {
+			String att = fields.get(i).getName();
+			Predicate p = root.get(att)
+					.in(StringTools.filterLessThanOrEqualToUtf8Length(FLAGS, JpaObjectTools.definedLength(cls, att)));
+			ps[i] = p;
+		}
+		list.addAll(em.createQuery(cq.select(root).where(cb.or(ps))).getResultList());
+		return list;
+	}
+
+	public <T extends JpaObject> T restrictFlag(String flag, Class<T> cls, String singularAttribute,
+			Object restrictValue) throws Exception {
+		return this.restrictFlag(flag, cls, singularAttribute, restrictValue,
+				this.entityManagerContainerFactory.getRestrictFlagFields(cls));
+	}
+
+	public <T extends JpaObject> T restrictFlag(String flag, Class<T> cls, String singularAttribute,
+			Object restrictValue, List<Field> fields) throws Exception {
+		EntityManager em = this.get(cls);
+		if (StringUtils.isEmpty(flag)) {
+			return null;
+		}
+		T t = null;
+		out: for (Field field : fields) {
+			if (!JpaObjectTools.withinDefinedLength(flag, cls, field)) {
+				continue;
+			}
+			CriteriaBuilder cb = em.getCriteriaBuilder();
+			CriteriaQuery<T> cq = cb.createQuery(cls);
+			Root<T> root = cq.from(cls);
+			Predicate p = cb.equal(root.get(field.getName()), flag);
+			p = cb.and(p, cb.equal(root.get(singularAttribute), restrictValue));
+			cq.select(root).where(p);
+			List<T> list = em.createQuery(cq).setMaxResults(2).getResultList();
+			switch (list.size()) {
+			case 0:
+				break;
+			case 1:
+				t = list.get(0);
+				break out;
+			case 2:
+				throw new Exception("flag get multiple entity flag:" + flag + ", class:" + cls.getName()
+						+ ", attribute:" + field.getName() + ", restrict attrubte:" + singularAttribute
+						+ ", restrict value:" + restrictValue + ".");
+			}
+		}
+		return t;
+	}
+
+	public <T extends JpaObject> List<T> list(Class<T> cls, String... ids) throws Exception {
+		return this.list(cls, false, ListTools.toList(ids));
+	}
+
+	public <T extends JpaObject> List<T> list(Class<T> cls, Collection<String> ids) throws Exception {
+		return this.list(cls, false, ids);
+	}
+
+	public <T extends JpaObject> List<T> list(Class<T> cls, boolean ordered, String... ids) throws Exception {
+		List<String> list = new ArrayList<>();
+		for (String str : ids) {
+			list.add(str);
+		}
+		return this.list(cls, ordered, list);
+	}
+
+	public <T extends JpaObject> List<T> list(Class<T> cls, boolean ordered, Collection<String> ids) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		final List<String> list = ListTools.trim(new ArrayList<>(ids), true, true);
+		cq.select(root).where(cb.isMember(root.get(JpaObject.id_FIELDNAME), cb.literal(list)));
+		List<T> os = em.createQuery(cq).getResultList();
+		if (!ordered) {
+			return new ArrayList<T>(os);
+		}
+		List<T> ordering = new ArrayList<>(os);
+		Collections.sort(ordering, new Comparator<T>() {
+			public int compare(T t1, T t2) {
+				return Integer.compare(list.indexOf(t1.getId()), list.indexOf(t2.getId()));
+			}
+		});
+		return ordering;
+	}
+
+	public <T extends JpaObject> List<T> listEqual(Class<T> cls, String attribute, Object value) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root).where(cb.equal(root.get(attribute), value));
+		List<T> os = em.createQuery(cq).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<T> listEqualAndEqual(Class<T> cls, String attribute, Object value,
+			String otherAttribute, Object otherValue) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root)
+				.where(cb.and(cb.equal(root.get(attribute), value), cb.equal(root.get(otherAttribute), otherValue)));
+		List<T> os = em.createQuery(cq).getResultList();
+		return new TreeList<T>(os);
+	}
+
+	public <T extends JpaObject, W extends Object> List<T> listEqualAndIn(Class<T> cls, String attribute, Object value,
+			String otherAttribute, Collection<W> otherValues) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		Predicate p = cb.equal(root.get(attribute), value);
+		p = cb.and(p, cb.isMember(root.get(otherAttribute), cb.literal(otherValues)));
+		List<T> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> Long countEqual(Class<T> cls, String attribute, Object value) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<T> root = cq.from(cls);
+		cq.select(cb.count(root)).where(cb.equal(root.get(attribute), value));
+		return em.createQuery(cq).getSingleResult();
+	}
+
+	public <T extends JpaObject> Long countEqual(Class<T> cls, String attribute, Object value, String otherAttribute,
+			Object otherValue) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<T> root = cq.from(cls);
+		cq.select(cb.count(root))
+				.where(cb.and(cb.equal(root.get(attribute), value), cb.equal(root.get(otherAttribute), otherValue)));
+		return em.createQuery(cq).getSingleResult();
+	}
+
+	public <T extends JpaObject> Long countEqualAndNotEqual(Class<T> cls, String attribute, Object value,
+			String otherAttribute, Object otherValue) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<T> root = cq.from(cls);
+		cq.select(cb.count(root)).where(cb.and(cb.equal(root.get(attribute), value),
+				cb.or(cb.isNull(root.get(otherAttribute)), cb.notEqual(root.get(otherAttribute), otherValue))));
+		return em.createQuery(cq).getSingleResult();
+	}
+
+	public <T extends JpaObject> List<T> listNotEqual(Class<T> cls, String attribute, Object value) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root).where(cb.or(cb.isNull(root.get(attribute)), cb.notEqual(root.get(attribute), value)));
+		List<T> os = em.createQuery(cq).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject, W extends Object> List<T> listIn(Class<T> cls, String attribute, Collection<W> values)
+			throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root).where(cb.isMember(root.get(attribute), cb.literal(values)));
+		List<T> os = em.createQuery(cq.distinct(true)).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<T> listIsMember(Class<T> cls, String attribute, Object value) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root).where(cb.isMember(value, root.get(attribute)));
+		List<T> os = em.createQuery(cq).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<T> listAll(Class<T> cls) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		List<T> os = em.createQuery(cq.select(root)).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<String> ids(Class<T> cls) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		cq.select(root.get(JpaObject.id_FIELDNAME));
+		List<String> os = em.createQuery(cq).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<String> idsEqual(Class<T> cls, String attribute, Object value) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		cq.select(root.get(JpaObject.id_FIELDNAME)).where(cb.equal(root.get(attribute), value));
+		List<String> os = em.createQuery(cq).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<String> idsEqualAndEqual(Class<T> cls, String attribute, Object value,
+			String otherAttribute, Object otherValue) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		Predicate p = cb.equal(root.get(attribute), value);
+		p = cb.and(p, cb.equal(root.get(otherAttribute), otherValue));
+		cq.select(root.get(JpaObject.id_FIELDNAME)).where(p);
+		List<String> os = em.createQuery(cq).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<String> idsNotEqual(Class<T> cls, String attribute, Object value)
+			throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		cq.select(root.get(JpaObject.id_FIELDNAME)).where(cb.notEqual(root.get(attribute), value));
+		List<String> os = em.createQuery(cq).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject, W extends Object> List<String> idsIn(Class<T> cls, String attribute,
+			Collection<W> values) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		cq.select(root.get(JpaObject.id_FIELDNAME)).where(cb.isMember(root.get(attribute), cb.literal(values)));
+		List<String> os = em.createQuery(cq.distinct(true)).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject, W extends Object> List<String> idsNotIn(Class<T> cls, String attribute,
+			Collection<W> values) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		cq.select(root.get(JpaObject.id_FIELDNAME)).where(cb.not(root.get(attribute).in(values)));
+		List<String> os = em.createQuery(cq.distinct(true)).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject, W extends Object> List<String> idsNotInAndEqual(Class<T> cls, String attribute,
+			Collection<W> values, String otherAttribute, Object otherValue) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		Predicate p = cb.not(root.get(attribute).in(values));
+		p = cb.and(p, cb.equal(root.get(otherAttribute), otherValue));
+		cq.select(root.get(JpaObject.id_FIELDNAME)).where(p);
+		List<String> os = em.createQuery(cq.distinct(true)).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<String> idsIsMember(Class<T> cls, String attribute, Object value)
+			throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		cq.select(root.get(JpaObject.id_FIELDNAME)).where(cb.isMember(value, root.get(attribute)));
+		List<String> os = em.createQuery(cq).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<String> idsLessThan(Class<T> cls, String attribute, Object value)
+			throws Exception {
+		EntityManager em = this.get(cls);
+		String str = "SELECT o.id FROM " + cls.getCanonicalName() + " o where o." + attribute + " < ?1";
+		TypedQuery<String> query = em.createQuery(str, String.class);
+		query.setParameter(1, value);
+		List<String> os = query.getResultList();
+		return new ArrayList<>(os);
+	}
+
+	public <T extends JpaObject> List<String> idsGreaterThan(Class<T> cls, String attribute, Object value)
+			throws Exception {
+		EntityManager em = this.get(cls);
+		String str = "SELECT o.id FROM " + cls.getCanonicalName() + " o where o." + attribute + " > ?1";
+		TypedQuery<String> query = em.createQuery(str, String.class);
+		query.setParameter(1, value);
+		List<String> os = query.getResultList();
+		return new ArrayList<>(os);
+	}
+
+	public <T extends JpaObject, W> List<String> idsEqualAndIn(Class<T> cls, String attribute, Object value,
+			String otherAttribute, Collection<W> otherValues) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<T> root = cq.from(cls);
+		Predicate p = cb.equal(root.get(attribute), value);
+		p = cb.and(p, cb.isMember(root.get(otherAttribute), cb.literal(otherValues)));
+		List<String> os = em.createQuery(cq.select(root.get(JpaObject.id_FIELDNAME)).where(p)).getResultList();
+		List<String> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public void commit() throws Exception {
+		try {
+			for (EntityManager em : entityManagerMap.values()) {
+				if ((null != em) && em.getTransaction().isActive()) {
+					em.getTransaction().commit();
+				}
+			}
+		} catch (Exception e) {
+			throw new Exception("commit error", e);
+		}
+	}
+
+	public void flush() throws Exception {
+		try {
+			for (EntityManager em : entityManagerMap.values()) {
+				if ((null != em) && em.getTransaction().isActive()) {
+					em.flush();
+				}
+			}
+		} catch (Exception e) {
+			throw new Exception("flush error", e);
+		}
+	}
+
+	public <T extends JpaObject> List<T> fetchAll(Class<T> clz) throws Exception {
+		return this.fetchAll(clz, JpaObject.singularAttributeField(clz, true, true));
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> List<W> fetchAll(Class<T> clz, WrapCopier<T, W> copier)
+			throws Exception {
+		return copier.copy(this.fetchAll(clz, copier.getCopyFields()));
+	}
+
+	public <T extends JpaObject> List<T> fetchAll(Class<T> clz, List<String> attributes) throws Exception {
+		List<T> list = new ArrayList<>();
+		List<String> fields = ListTools.trim(attributes, true, true, JpaObject.id_FIELDNAME);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : fields) {
+			selections.add(root.get(str));
+		}
+		for (Tuple o : em.createQuery(cq.multiselect(selections)).getResultList()) {
+			T t = clz.newInstance();
+			for (int i = 0; i < fields.size(); i++) {
+				PropertyUtils.setProperty(t, attributes.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		return list;
+	}
+
+	public <T extends JpaObject> T fetch(String id, Class<T> clz) throws Exception {
+		return this.fetch(id, clz, JpaObject.singularAttributeField(clz, true, true));
+	}
+
+	public <T extends JpaObject> T fetch(String id, Class<T> clz, List<String> attributes) throws Exception {
+		T t = null;
+		if (StringUtils.isEmpty(id)) {
+			return null;
+		}
+		if (!attributes.contains(JpaObject.id_FIELDNAME)) {
+			attributes.add(JpaObject.id_FIELDNAME);
+		}
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : attributes) {
+			selections.add(root.get(str));
+		}
+		cq.multiselect(selections).where(cb.equal(root.get(JpaObject.id_FIELDNAME), id));
+		List<Tuple> list = em.createQuery(cq).setMaxResults(1).getResultList();
+		if (!list.isEmpty()) {
+			Tuple tuple = list.get(0);
+			t = clz.newInstance();
+			for (int i = 0; i < selections.size(); i++) {
+				PropertyUtils.setProperty(t, attributes.get(i), tuple.get(selections.get(i)));
+			}
+		}
+		return t;
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> T fetch(String id, Class<T> clz, Class<W> wrapClass)
+			throws Exception {
+		List<String> list = new ArrayList<>();
+		for (Field field : FieldUtils.getAllFields(wrapClass)) {
+			Field jpaField = FieldUtils.getField(clz, field.getName(), true);
+			if ((null != jpaField) && (!Collection.class.isAssignableFrom(jpaField.getType()))) {
+				list.add(field.getName());
+			}
+		}
+		return this.fetch(id, clz, list);
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> W fetch(String id, WrapCopier<T, W> copier)
+			throws Exception {
+		T t = this.fetch(id, copier.getOrigClass(), copier.getCopyFields());
+		return copier.copy(t);
+	}
+
+	public <T extends JpaObject> List<T> fetch(Collection<String> ids, Class<T> clz) throws Exception {
+		return this.fetch(ids, clz, JpaObject.singularAttributeField(clz, true, true));
+	}
+
+	public <T extends JpaObject> List<T> fetch(Collection<String> ids, Class<T> clz, List<String> attributes)
+			throws Exception {
+		List<T> list = new ArrayList<>();
+		if (ids.isEmpty()) {
+			return list;
+		}
+		List<String> idList = new ArrayList<>(ids);
+		if (!attributes.contains(JpaObject.id_FIELDNAME)) {
+			attributes.add(JpaObject.id_FIELDNAME);
+		}
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : attributes) {
+			selections.add(root.get(str));
+		}
+		cq.multiselect(selections).where(root.get(JpaObject.id_FIELDNAME).in(idList));
+		for (Tuple o : em.createQuery(cq).getResultList()) {
+			T t = clz.newInstance();
+			for (int i = 0; i < attributes.size(); i++) {
+				PropertyUtils.setProperty(t, attributes.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		List<T> ordering = new ArrayList<>(list);
+		Collections.sort(ordering, new Comparator<T>() {
+			public int compare(T t1, T t2) {
+				return Integer.compare(idList.indexOf(t1.getId()), idList.indexOf(t2.getId()));
+			}
+		});
+		return ordering;
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> List<T> fetch(Collection<String> ids, Class<T> clz,
+			Class<W> wrapClass) throws Exception {
+		List<String> list = new ArrayList<>();
+		for (Field field : FieldUtils.getAllFields(wrapClass)) {
+			Field jpaField = FieldUtils.getField(clz, field.getName(), true);
+			if ((null != jpaField) && (!Collection.class.isAssignableFrom(jpaField.getType()))) {
+				list.add(field.getName());
+			}
+		}
+		return this.fetch(ids, clz, list);
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> List<W> fetch(Collection<String> ids,
+			WrapCopier<T, W> copier) throws Exception {
+		List<T> os = this.fetch(ids, copier.getOrigClass(), copier.getCopyFields());
+		return copier.copy(os);
+	}
+
+	public <T extends JpaObject> List<T> fetchEqual(Class<T> clz, String attribute, Object value) throws Exception {
+		List<T> os = this.fetchEqual(clz, JpaObject.singularAttributeField(clz, true, true), attribute, value);
+		return os;
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> List<W> fetchEqual(Class<T> clz, WrapCopier<T, W> copier,
+			String attribute, Object value) throws Exception {
+		List<T> os = this.fetchEqual(clz, copier.getCopyFields(), attribute, value);
+		return copier.copy(os);
+	}
+
+	public <T extends JpaObject> List<T> fetchEqual(Class<T> clz, List<String> attributes, String attribute,
+			Object value) throws Exception {
+		List<T> list = new ArrayList<>();
+		List<String> fields = ListTools.trim(attributes, true, true, JpaObject.id_FIELDNAME);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : fields) {
+			selections.add(root.get(str));
+		}
+		Predicate p = cb.equal(root.get(attribute), value);
+		cq.multiselect(selections).where(p);
+		for (Tuple o : em.createQuery(cq).getResultList()) {
+			T t = clz.newInstance();
+			for (int i = 0; i < fields.size(); i++) {
+				PropertyUtils.setProperty(t, fields.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		return list;
+	}
+
+	public <T extends JpaObject> List<T> fetchEqualAndEqual(Class<T> clz, String attribute, Object value,
+			String otherAttribute, Object otherValue) throws Exception {
+		List<T> os = this.fetchEqualAndEqual(clz, JpaObject.singularAttributeField(clz, true, true), attribute, value,
+				otherAttribute, otherValue);
+		return os;
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> List<W> fetchEqualAndEqual(Class<T> clz,
+			WrapCopier<T, W> copier, String attribute, Object value, String otherAttribute, Object otherValue)
+			throws Exception {
+		List<T> os = this.fetchEqualAndEqual(clz, copier.getCopyFields(), attribute, value, otherAttribute, otherValue);
+		return copier.copy(os);
+	}
+
+	public <T extends JpaObject> List<T> fetchEqualAndEqual(Class<T> clz, List<String> fetchAttributes,
+			String attribute, Object value, String otherAttribute, Object otherValue) throws Exception {
+		List<T> list = new ArrayList<>();
+		List<String> fields = ListTools.trim(fetchAttributes, true, true, JpaObject.id_FIELDNAME);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : fields) {
+			selections.add(root.get(str));
+		}
+		Predicate p = cb.and(cb.equal(root.get(attribute), value), cb.equal(root.get(otherAttribute), otherValue));
+		cq.multiselect(selections).where(p);
+		for (Tuple o : em.createQuery(cq).getResultList()) {
+			T t = clz.newInstance();
+			for (int i = 0; i < fields.size(); i++) {
+				PropertyUtils.setProperty(t, fields.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		return list;
+	}
+
+	public <T extends JpaObject> List<T> fetchNotEqual(Class<T> clz, String attribute, Object value) throws Exception {
+		List<T> os = this.fetchNotEqual(clz, JpaObject.singularAttributeField(clz, true, true), attribute, value);
+		return os;
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> List<W> fetchNotEqual(Class<T> clz,
+			WrapCopier<T, W> copier, String attribute, Object value) throws Exception {
+		List<T> os = this.fetchNotEqual(clz, copier.getCopyFields(), attribute, value);
+		return copier.copy(os);
+	}
+
+	public <T extends JpaObject> List<T> fetchNotEqual(Class<T> clz, List<String> attributes, String attribute,
+			Object value) throws Exception {
+		List<T> list = new ArrayList<>();
+		List<String> fields = ListTools.trim(attributes, true, true, JpaObject.id_FIELDNAME);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : fields) {
+			selections.add(root.get(str));
+		}
+		Predicate p = cb.or(cb.isNull(root.get(attribute)), cb.notEqual(root.get(attribute), value));
+		cq.multiselect(selections).where(p);
+		for (Tuple o : em.createQuery(cq).getResultList()) {
+			T t = clz.newInstance();
+			for (int i = 0; i < fields.size(); i++) {
+				PropertyUtils.setProperty(t, fields.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		return list;
+	}
+
+	public <T extends JpaObject, V extends Object> List<T> fetchIn(Class<T> clz, String attribute, Collection<V> values)
+			throws Exception {
+		List<T> os = this.fetchIn(clz, JpaObject.singularAttributeField(clz, true, true), attribute, values);
+		return os;
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject, V extends Object> List<W> fetchIn(Class<T> clz,
+			WrapCopier<T, W> copier, String attribute, Collection<V> values) throws Exception {
+		List<T> os = this.fetchIn(clz, copier.getCopyFields(), attribute, values);
+		return copier.copy(os);
+	}
+
+	public <T extends JpaObject, W extends Object> List<T> fetchIn(Class<T> clz, List<String> attributes,
+			String attribute, Collection<W> values) throws Exception {
+		List<T> list = new ArrayList<>();
+		List<String> fields = ListTools.trim(attributes, true, true, JpaObject.id_FIELDNAME);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : fields) {
+			selections.add(root.get(str));
+		}
+		Predicate p = cb.isMember(root.get(attribute), cb.literal(values));
+		cq.multiselect(selections).where(p);
+		for (Tuple o : em.createQuery(cq).getResultList()) {
+			T t = clz.newInstance();
+			for (int i = 0; i < fields.size(); i++) {
+				PropertyUtils.setProperty(t, fields.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		return list;
+	}
+
+	public <T extends JpaObject, V extends Object> List<T> fetchEqualAndIn(Class<T> clz, String attribute, Object value,
+			String otherAttribute, Collection<V> otherValues) throws Exception {
+		List<T> os = this.fetchEqualAndIn(clz, JpaObject.singularAttributeField(clz, true, true), attribute, value,
+				otherAttribute, otherValues);
+		return os;
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject, V extends Object> List<W> fetchEqualAndIn(Class<T> clz,
+			WrapCopier<T, W> copier, String attribute, Object value, String otherAttribute, Collection<V> otherValues)
+			throws Exception {
+		List<T> os = this.fetchEqualAndIn(clz, copier.getCopyFields(), attribute, value, otherAttribute, otherValues);
+		return copier.copy(os);
+	}
+
+	public <T extends JpaObject, V extends Object> List<T> fetchEqualAndIn(Class<T> clz, List<String> fetchAttributes,
+			String attribute, Object value, String otherAttribute, Collection<V> otherValues) throws Exception {
+		List<T> list = new ArrayList<>();
+		List<String> fields = ListTools.trim(fetchAttributes, true, true, JpaObject.id_FIELDNAME);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : fields) {
+			selections.add(root.get(str));
+		}
+		Predicate p = cb.and(cb.equal(root.get(attribute), value),
+				cb.isMember(root.get(otherAttribute), cb.literal(otherValues)));
+		cq.multiselect(selections).where(p);
+		for (Tuple o : em.createQuery(cq).getResultList()) {
+			T t = clz.newInstance();
+			for (int i = 0; i < fields.size(); i++) {
+				PropertyUtils.setProperty(t, fields.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		return list;
+	}
+
+	public <T extends JpaObject> List<T> fetchIsMember(Class<T> clz, String attribute, Object value) throws Exception {
+		List<T> os = this.fetchIsMember(clz, JpaObject.singularAttributeField(clz, true, true), attribute, value);
+		return os;
+	}
+
+	public <T extends JpaObject, W extends GsonPropertyObject> List<W> fetchIsMember(Class<T> clz,
+			WrapCopier<T, W> copier, String attribute, Object value) throws Exception {
+		List<T> os = this.fetchIsMember(clz, copier.getCopyFields(), attribute, value);
+		return copier.copy(os);
+	}
+
+	public <T extends JpaObject> List<T> fetchIsMember(Class<T> clz, List<String> attributes, String attribute,
+			Object value) throws Exception {
+		List<T> list = new ArrayList<>();
+		List<String> fields = ListTools.trim(attributes, true, true, JpaObject.id_FIELDNAME);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : fields) {
+			selections.add(root.get(str));
+		}
+		Predicate p = cb.isMember(value, root.get(attribute));
+		cq.multiselect(selections).where(p);
+		for (Tuple o : em.createQuery(cq).getResultList()) {
+			T t = clz.newInstance();
+			for (int i = 0; i < fields.size(); i++) {
+				PropertyUtils.setProperty(t, fields.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		return list;
+	}
+
+	public <T extends JpaObject> Integer delete(Class<T> clz, Collection<String> ids) throws Exception {
+		int i = 0;
+		if (!ids.isEmpty()) {
+			EntityManager em = this.get(clz);
+			for (String id : ids) {
+				if (StringUtils.isNotEmpty(id)) {
+					T t = em.find(clz, id);
+					if (null != t) {
+						em.remove(t);
+						i++;
+					}
+				}
+			}
+		}
+		return i;
+	}
+
+	public <T extends JpaObject> Integer delete(Class<T> clz, String... ids) throws Exception {
+		List<String> list = new ArrayList<>();
+		for (String o : ids) {
+			list.add(o);
+		}
+		return this.delete(clz, list);
+	}
+
+	public <T extends JpaObject> List<T> deleteEqual(Class<T> cls, String attribute, Object value) throws Exception {
+		List<T> os = this.listEqual(cls, attribute, value);
+		os.stream().forEach(o -> {
+			try {
+				this.remove(o);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		});
+		return os;
+	}
+
+	public <T extends JpaObject> List<T> deleteEqualAndEqual(Class<T> cls, String attribute, Object value,
+			String otherAttribute, Object otherValue) throws Exception {
+		List<T> os = this.listEqualAndEqual(cls, attribute, value, otherAttribute, otherValue);
+		os.stream().forEach(o -> {
+			try {
+				this.remove(o);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		});
+		return os;
+	}
+
+	public <T extends JpaObject> boolean duplicateWithFlags(Class<T> clz, String... value) throws Exception {
+		List<String> list = Arrays.asList(value);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<T> root = cq.from(clz);
+		Predicate p = cb.disjunction();
+		for (Field field : this.entityManagerContainerFactory.getFlagFields(clz)) {
+			p = cb.or(p, root.get(field.getName())
+					.in(StringTools.filterLessThanOrEqualToUtf8Length(list, JpaObjectTools.definedLength(clz, field))));
+		}
+		return em.createQuery(cq.select(cb.count(root)).where(p)).getSingleResult() > 0;
+	}
+
+	public <T extends JpaObject> boolean duplicateWithFlags(String excludeId, Class<T> clz, String... value)
+			throws Exception {
+		List<String> list = Arrays.asList(value);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<T> root = cq.from(clz);
+		Predicate p = cb.disjunction();
+		for (Field field : this.entityManagerContainerFactory.getFlagFields(clz)) {
+			p = cb.or(p, root.get(field.getName())
+					.in(StringTools.filterLessThanOrEqualToUtf8Length(list, JpaObjectTools.definedLength(clz, field))));
+		}
+		p = cb.and(p, cb.notEqual(root.get(JpaObject.id_FIELDNAME), excludeId));
+		return em.createQuery(cq.select(cb.count(root)).where(p)).getSingleResult() > 0;
+	}
+
+	public <T extends JpaObject> boolean duplicateWithFlags(List<String> excludeIds, Class<T> clz, String... value)
+			throws Exception {
+		List<String> list = Arrays.asList(value);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<T> root = cq.from(clz);
+		Predicate p = cb.disjunction();
+		for (Field field : this.entityManagerContainerFactory.getFlagFields(clz)) {
+			p = cb.or(p, root.get(field.getName())
+					.in(StringTools.filterLessThanOrEqualToUtf8Length(list, JpaObjectTools.definedLength(clz, field))));
+		}
+		p = cb.and(p, cb.not(root.get(JpaObject.id_FIELDNAME).in(excludeIds)));
+		return em.createQuery(cq.select(cb.count(root)).where(p)).getSingleResult() > 0;
+	}
+
+	public <T extends JpaObject> boolean duplicateWithRestrictFlags(Class<T> clz, String restrictSingularAttribute,
+			Object restrictValue, String excludeId, List<String> values) throws Exception {
+		values = ListTools.trim(values, true, true);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<T> root = cq.from(clz);
+		Predicate p = cb.disjunction();
+		for (Field field : this.entityManagerContainerFactory.getFlagFields(clz)) {
+			p = cb.or(p, root.get(field.getName()).in(StringTools.filterLessThanOrEqualToUtf8Length(values,
+					JpaObjectTools.definedLength(clz, field.getName()))));
+		}
+		if (StringUtils.isNotEmpty(excludeId)) {
+			p = cb.and(p, cb.notEqual(root.get(JpaObject.id_FIELDNAME), excludeId));
+		}
+		return em.createQuery(cq.select(cb.count(root)).where(p)).getSingleResult() > 0;
+	}
+
+	public <T extends JpaObject, W> List<W> select(Class<T> cls, String attribute, Class<W> attributeClass)
+			throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<W> cq = cb.createQuery(attributeClass);
+		Root<T> root = cq.from(cls);
+		List<W> os = em.createQuery(cq.select(root.get(attribute))).getResultList();
+		List<W> list = new ArrayList<>(os);
+		return list;
+	}
+}

+ 132 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/EntityManagerContainerBasic.java

@@ -0,0 +1,132 @@
+package com.x.base.core.container;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
+
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.JpaObject;
+
+public abstract class EntityManagerContainerBasic implements AutoCloseable {
+
+	protected EntityManagerContainerBasic(EntityManagerContainerFactory entityManagerContainerFactory) {
+		this.entityManagerContainerFactory = entityManagerContainerFactory;
+		this.persistChecker = new PersistChecker(this);
+		this.removeChecker = new RemoveChecker(this);
+	}
+
+	protected PersistChecker persistChecker;
+	protected RemoveChecker removeChecker;
+
+	protected EntityManagerContainerFactory entityManagerContainerFactory;
+
+	protected Map<Class<? extends JpaObject>, EntityManager> entityManagerMap = new ConcurrentHashMap<Class<? extends JpaObject>, EntityManager>();
+
+	public <T extends JpaObject> EntityManager get(Class<T> cls) throws Exception {
+		Class<T> clazz = (Class<T>) entityManagerContainerFactory.assignableFrom(cls);
+		EntityManager em = fromEntityManagers(clazz);
+		if (null == em) {
+			em = entityManagerContainerFactory.createEntityManager(clazz);
+			em.setFlushMode(FlushModeType.COMMIT);
+			entityManagerMap.put(cls, em);
+		}
+		return em;
+	}
+
+	public <T extends JpaObject> EntityManager beginTransaction(Class<T> cls) throws Exception {
+		EntityManager em = get(cls);
+		if (!em.getTransaction().isActive()) {
+			em.getTransaction().begin();
+		}
+		return em;
+	}
+
+	private EntityManager fromEntityManagers(Class<?> cls) {
+		EntityManager em = entityManagerMap.get(cls);
+		if ((null != em) && em.isOpen()) {
+			return em;
+		}
+		return null;
+	}
+
+	public void rollback() {
+		for (EntityManager em : entityManagerMap.values()) {
+			if ((null != em) && em.getTransaction().isActive()) {
+				em.getTransaction().rollback();
+			}
+		}
+	}
+
+	public void close() {
+		for (EntityManager em : entityManagerMap.values()) {
+			if (null != em && em.isOpen()) {
+				if (em.getTransaction().isActive()) {
+					em.getTransaction().rollback();
+				}
+				em.close();
+			}
+		}
+	}
+
+	protected FieldType getFieldType(Field field) throws Exception {
+		if (field.getType().isAssignableFrom(String.class)) {
+			return FieldType.stringValue;
+		}
+		if (field.getType().isAssignableFrom(Integer.class)) {
+			return FieldType.integerValue;
+		}
+		if (field.getType().isAssignableFrom(Double.class)) {
+			return FieldType.doubleValue;
+		}
+		if (field.getType().isAssignableFrom(Long.class)) {
+			return FieldType.longValue;
+		}
+		if (field.getType().isAssignableFrom(Float.class)) {
+			return FieldType.floatValue;
+		}
+		if (field.getType().isAssignableFrom(Date.class)) {
+			return FieldType.dateValue;
+		}
+		if (field.getType().isAssignableFrom(Boolean.class)) {
+			return FieldType.booleanValue;
+		}
+		if (field.getType().isAssignableFrom((new byte[] {}).getClass())) {
+			return FieldType.byteValueArray;
+		}
+		if (List.class.isAssignableFrom(field.getType())) {
+			ParameterizedType parameterized = (ParameterizedType) field.getGenericType();
+			Class<?> actualClass = (Class<?>) parameterized.getActualTypeArguments()[0];
+			if (String.class.isAssignableFrom(actualClass)) {
+				return FieldType.stringValueList;
+			}
+			if (Integer.class.isAssignableFrom(actualClass)) {
+				return FieldType.integerValueList;
+			}
+			if (Double.class.isAssignableFrom(actualClass)) {
+				return FieldType.doubleValueList;
+			}
+			if (Long.class.isAssignableFrom(actualClass)) {
+				return FieldType.longValueList;
+			}
+			if (Float.class.isAssignableFrom(actualClass)) {
+				return FieldType.floatValueList;
+			}
+			if (Date.class.isAssignableFrom(actualClass)) {
+				return FieldType.dateValueList;
+			}
+			if (Boolean.class.isAssignableFrom(actualClass)) {
+				return FieldType.booleanValueList;
+			}
+		}
+		if (field.getType().isEnum()){
+			return FieldType.enumValue;
+		}
+		throw new Exception("unknow filed type{name:" + field.getName() + "}.");
+	}
+}

+ 32 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/FactorDistributionPolicy.java

@@ -0,0 +1,32 @@
+package com.x.base.core.container;
+
+import java.util.List;
+import java.util.Random;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.openjpa.slice.DistributionPolicy;
+
+import com.x.base.core.entity.SliceJpaObject;
+
+public class FactorDistributionPolicy implements DistributionPolicy {
+
+	private Random random = new Random();
+
+	public String distribute(Object pc, List<String> slices, Object context) {
+		try {
+			Object o = PropertyUtils.getProperty(pc, SliceJpaObject.distributeFactor_FIELDNAME);
+			Integer factor = null;
+			if (null == o) {
+				factor = random.nextInt(1000);
+				PropertyUtils.setProperty(pc, SliceJpaObject.distributeFactor_FIELDNAME, factor);
+			} else {
+				factor = (Integer) o;
+			}
+			return slices.get(factor % slices.size());
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+}

+ 22 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/FieldType.java

@@ -0,0 +1,22 @@
+package com.x.base.core.container;
+
+public enum FieldType {
+	/* string */
+	stringValue, stringValueList,
+	/* boolean */
+	booleanValue, booleanValueList,
+	/* integer */
+	integerValue, integerValueList,
+	/* double */
+	doubleValue, doubleValueList,
+	/* long */
+	longValue, longValueList,
+	/* float */
+	floatValue, floatValueList,
+	/* date */
+	dateValue, dateValueList,
+	/* byte */
+	byteValueArray,
+	/* enum */
+	enumValue;
+}

+ 5 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/LogLevel.java

@@ -0,0 +1,5 @@
+package com.x.base.core.container;
+
+public enum LogLevel {
+	FATAL, ERROR, WARN, INFO, TRACE
+}

+ 55 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/PersistChecker.java

@@ -0,0 +1,55 @@
+package com.x.base.core.container;
+
+import com.x.base.core.container.checker.BooleanValueListPersistChecker;
+import com.x.base.core.container.checker.BooleanValuePersistChecker;
+import com.x.base.core.container.checker.ByteValueArrayPersistChecker;
+import com.x.base.core.container.checker.DateValueListPersistChecker;
+import com.x.base.core.container.checker.DateValuePersistChecker;
+import com.x.base.core.container.checker.DoubleValueListPersistChecker;
+import com.x.base.core.container.checker.DoubleValuePersistChecker;
+import com.x.base.core.container.checker.FloatValueListPersistChecker;
+import com.x.base.core.container.checker.FloatValuePersistChecker;
+import com.x.base.core.container.checker.IntegerValueListPersistChecker;
+import com.x.base.core.container.checker.IntegerValuePersistChecker;
+import com.x.base.core.container.checker.LongValueListPersistChecker;
+import com.x.base.core.container.checker.LongValuePersistChecker;
+import com.x.base.core.container.checker.StringValueListPersistChecker;
+import com.x.base.core.container.checker.StringValuePersistChecker;
+
+public class PersistChecker {
+
+	public PersistChecker(EntityManagerContainerBasic emc) {
+		this.stringValue = new StringValuePersistChecker(emc);
+		this.stringValueList = new StringValueListPersistChecker(emc);
+		this.booleanValue = new BooleanValuePersistChecker(emc);
+		this.booleanValueList = new BooleanValueListPersistChecker(emc);
+		this.dateValue = new DateValuePersistChecker(emc);
+		this.dateValueList = new DateValueListPersistChecker(emc);
+		this.integerValue = new IntegerValuePersistChecker(emc);
+		this.integerValueList = new IntegerValueListPersistChecker(emc);
+		this.doubleValue = new DoubleValuePersistChecker(emc);
+		this.doubleValueList = new DoubleValueListPersistChecker(emc);
+		this.longValue = new LongValuePersistChecker(emc);
+		this.longValueList = new LongValueListPersistChecker(emc);
+		this.floatValue = new FloatValuePersistChecker(emc);
+		this.floatValueList = new FloatValueListPersistChecker(emc);
+		this.byteValueArray = new ByteValueArrayPersistChecker(emc);
+	}
+
+	public StringValuePersistChecker stringValue;
+	public StringValueListPersistChecker stringValueList;
+	public BooleanValuePersistChecker booleanValue;
+	public BooleanValueListPersistChecker booleanValueList;
+	public DateValuePersistChecker dateValue;
+	public DateValueListPersistChecker dateValueList;
+	public IntegerValuePersistChecker integerValue;
+	public IntegerValueListPersistChecker integerValueList;
+	public DoubleValuePersistChecker doubleValue;
+	public DoubleValueListPersistChecker doubleValueList;
+	public LongValuePersistChecker longValue;
+	public LongValueListPersistChecker longValueList;
+	public FloatValuePersistChecker floatValue;
+	public FloatValueListPersistChecker floatValueList;
+	public ByteValueArrayPersistChecker byteValueArray;
+
+}

+ 15 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/RemoveChecker.java

@@ -0,0 +1,15 @@
+package com.x.base.core.container;
+
+import com.x.base.core.container.checker.StringValueListRemoveChecker;
+import com.x.base.core.container.checker.StringValueRemoveChecker;
+
+public class RemoveChecker {
+
+	public RemoveChecker(EntityManagerContainerBasic emc) {
+		this.stringValue = new StringValueRemoveChecker(emc);
+		this.stringValueList = new StringValueListRemoveChecker(emc);
+	}
+
+	public StringValueRemoveChecker stringValue;
+	public StringValueListRemoveChecker stringValueList;
+}

+ 13 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/AbstractChecker.java

@@ -0,0 +1,13 @@
+package com.x.base.core.container.checker;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+
+public abstract class AbstractChecker {
+
+	protected AbstractChecker(EntityManagerContainerBasic emc) {
+		this.emc = emc;
+	}
+
+	protected EntityManagerContainerBasic emc;
+
+}

+ 50 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/BooleanValueListPersistChecker.java

@@ -0,0 +1,50 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.tools.ListTools;
+
+public class BooleanValueListPersistChecker extends AbstractChecker {
+
+	public BooleanValueListPersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, List<Boolean> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.allowContainEmpty(field, values, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, List<Boolean> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (ListTools.nullToEmpty(values).isEmpty())) {
+			throw new Exception("check persist booleanValueList allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or empty.");
+		}
+	}
+
+	private void allowContainEmpty(Field field, List<Boolean> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (!checkPersist.allowContainEmpty()) {
+			for (Boolean o : ListTools.nullToEmpty(values)) {
+				if (null == o) {
+					throw new Exception("check persist booleanValueList allowContainEmpty error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ",values:"
+							+ StringUtils.join(values, ",") + " can not contain null.");
+				}
+			}
+		}
+	}
+}

+ 32 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/BooleanValuePersistChecker.java

@@ -0,0 +1,32 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+
+public class BooleanValuePersistChecker extends AbstractChecker {
+
+	public BooleanValuePersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, Boolean value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, value, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, Boolean value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (value == null)) {
+			throw new Exception("check persist booleanValue allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null.");
+		}
+	}
+}

+ 32 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/ByteValueArrayPersistChecker.java

@@ -0,0 +1,32 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+
+public class ByteValueArrayPersistChecker extends AbstractChecker {
+
+	public ByteValueArrayPersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, byte[] values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, values, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, byte[] values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (values == null || values.length == 0)) {
+			throw new Exception("check persist byteValueArray allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or empty.");
+		}
+	}
+}

+ 82 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/DateValueListPersistChecker.java

@@ -0,0 +1,82 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.tools.DateTools;
+import com.x.base.core.project.tools.ListTools;
+
+public class DateValueListPersistChecker extends AbstractChecker {
+
+	public DateValueListPersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, List<Date> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.allowContainEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.max(field, values, jpa, checkPersist, checkPersistType);
+			this.min(field, values, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, List<Date> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (ListTools.nullToEmpty(values).isEmpty())) {
+			throw new Exception("check persist dateValueList allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or empty.");
+		}
+	}
+
+	private void allowContainEmpty(Field field, List<Date> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (!checkPersist.allowContainEmpty()) {
+			for (Date o : ListTools.nullToEmpty(values)) {
+				if (null == o) {
+					throw new Exception("check persist dateValueList allowContainEmpty error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", can not contain null.");
+				}
+			}
+
+		}
+	}
+
+	private void max(Field field, List<Date> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max())) {
+			Date date = DateTools.parse(checkPersist.max());
+			for (Date o : ListTools.nullToEmpty(values)) {
+				if (null != o && o.after(date)) {
+					throw new Exception(
+							"check persist dateValueList max error, class:" + jpa.getClass().getName() + ", field:"
+									+ field.getName() + ", can not contain value after:" + checkPersist.max() + ".");
+				}
+			}
+		}
+	}
+
+	private void min(Field field, List<Date> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min())) {
+			Date date = DateTools.parse(checkPersist.min());
+			for (Date o : ListTools.nullToEmpty(values)) {
+				if (null != o && o.before(date)) {
+					throw new Exception(
+							"check persist dateValueList min error, class:" + jpa.getClass().getName() + ", field:"
+									+ field.getName() + ", can not contain value before:" + checkPersist.min() + ".");
+				}
+			}
+		}
+	}
+}

+ 60 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/DateValuePersistChecker.java

@@ -0,0 +1,60 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.Date;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.tools.DateTools;
+
+public class DateValuePersistChecker extends AbstractChecker {
+
+	public DateValuePersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, Date value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, value, jpa, checkPersist, checkPersistType);
+			this.max(field, value, jpa, checkPersist, checkPersistType);
+			this.min(field, value, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, Date value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (value == null)) {
+			throw new Exception("check persist dateValue allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null.");
+		}
+	}
+
+	private void max(Field field, Date value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max()) && (value != null)) {
+			Date date = DateTools.parse(checkPersist.max());
+			if (value.after(date)) {
+				throw new Exception("check persist dateValue max error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not after:" + checkPersist.max() + ".");
+			}
+		}
+	}
+
+	private void min(Field field, Date value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min()) && (value != null)) {
+			Date date = DateTools.parse(checkPersist.min());
+			if (value.before(date)) {
+				throw new Exception("check persist dateValue min error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not before:" + checkPersist.min() + ".");
+			}
+		}
+	}
+}

+ 81 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/DoubleValueListPersistChecker.java

@@ -0,0 +1,81 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.tools.ListTools;
+
+public class DoubleValueListPersistChecker extends AbstractChecker {
+
+	public DoubleValueListPersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, List<Double> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.allowContainEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.max(field, values, jpa, checkPersist, checkPersistType);
+			this.min(field, values, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, List<Double> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (ListTools.nullToEmpty(values).isEmpty())) {
+			throw new Exception("check persist doubleValueList allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or empty.");
+		}
+	}
+
+	private void allowContainEmpty(Field field, List<Double> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (!checkPersist.allowContainEmpty()) {
+			for (Double o : ListTools.nullToEmpty(values)) {
+				if (null == o) {
+					throw new Exception("check persist doubleValueList allowContainEmpty error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", can not contain null.");
+				}
+			}
+
+		}
+	}
+
+	private void max(Field field, List<Double> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max())) {
+			Double max = Double.parseDouble(checkPersist.max());
+			for (Double o : ListTools.nullToEmpty(values)) {
+				if (null != o && o > max) {
+					throw new Exception("check persist doubleValueList max error, class:" + jpa.getClass().getName()
+							+ ", field:" + field.getName() + ", can not contain value larger than:" + checkPersist.max()
+							+ ".");
+				}
+			}
+
+		}
+	}
+
+	private void min(Field field, List<Double> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min())) {
+			Double min = Double.parseDouble(checkPersist.min());
+			for (Double o : ListTools.nullToEmpty(values)) {
+				if (null != o && o < min) {
+					throw new Exception("check doubleValueList min error, class:" + jpa.getClass().getName()
+							+ ", field:" + field.getName() + ", can not contain value lesser than:" + checkPersist.min()
+							+ ".");
+				}
+			}
+		}
+	}
+}

+ 58 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/DoubleValuePersistChecker.java

@@ -0,0 +1,58 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+
+public class DoubleValuePersistChecker extends AbstractChecker {
+
+	public DoubleValuePersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, Double value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, value, jpa, checkPersist, checkPersistType);
+			this.max(field, value, jpa, checkPersist, checkPersistType);
+			this.min(field, value, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, Double value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (null == value)) {
+			throw new Exception("check persist doubleValue allowEmpty error, class:" + jpa.getClass().getName() + ", field:"
+					+ field.getName() + ", can not be null.");
+		}
+	}
+
+	private void max(Field field, Double value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max()) && (null != value)) {
+			Double max = Double.parseDouble(checkPersist.max());
+			if (max < value) {
+				throw new Exception("check persist doubleValue max error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not larger then:" + checkPersist.max() + ".");
+			}
+		}
+	}
+
+	private void min(Field field, Double value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min()) && (null != value)) {
+			Double min = Double.parseDouble(checkPersist.min());
+			if (min > value) {
+				throw new Exception("check persist doubleValue min error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not lesser then:" + checkPersist.min() + ".");
+			}
+		}
+	}
+}

+ 79 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/FloatValueListPersistChecker.java

@@ -0,0 +1,79 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.tools.ListTools;
+
+public class FloatValueListPersistChecker extends AbstractChecker {
+
+	public FloatValueListPersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, List<Float> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.allowContainEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.max(field, values, jpa, checkPersist, checkPersistType);
+			this.min(field, values, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, List<Float> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (ListTools.nullToEmpty(values).isEmpty())) {
+			throw new Exception("check persist floatValueList allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or empty.");
+		}
+	}
+
+	private void allowContainEmpty(Field field, List<Float> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (!checkPersist.allowContainEmpty()) {
+			for (Float o : ListTools.nullToEmpty(values)) {
+				if (null == o) {
+					throw new Exception("check persist floatValueList allowContainEmpty error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", can not contain null.");
+				}
+			}
+
+		}
+	}
+
+	private void max(Field field, List<Float> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max())) {
+			Float max = Float.parseFloat(checkPersist.max());
+			for (Float o : ListTools.nullToEmpty(values)) {
+				if (null != o && o > max) {
+					throw new Exception("check persist floatValueList max error, class:" + jpa.getClass().getName()
+							+ ", field:" + field.getName() + ", can not contain value larger than:" + checkPersist.max()
+							+ ".");
+				}
+			}
+		}
+	}
+
+	private void min(Field field, List<Float> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min())) {
+			Float min = Float.parseFloat(checkPersist.min());
+			for (Float o : ListTools.nullToEmpty(values)) {
+				if (null != o && o < min) {
+					throw new Exception("check floatValueList min error, class:" + jpa.getClass().getName() + ", field:"
+							+ field.getName() + ", can not contain value lesser than:" + checkPersist.min() + ".");
+				}
+			}
+		}
+	}
+}

+ 58 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/FloatValuePersistChecker.java

@@ -0,0 +1,58 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+
+public class FloatValuePersistChecker extends AbstractChecker {
+
+	public FloatValuePersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, Float value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, value, jpa, checkPersist, checkPersistType);
+			this.max(field, value, jpa, checkPersist, checkPersistType);
+			this.min(field, value, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, Float value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (null == value)) {
+			throw new Exception("check persist floatValue allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null.");
+		}
+	}
+
+	private void max(Field field, Float value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max()) && (null != value)) {
+			Float max = Float.parseFloat(checkPersist.max());
+			if (max < value) {
+				throw new Exception("check persist floatValue max error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not larger then:" + checkPersist.max() + ".");
+			}
+		}
+	}
+
+	private void min(Field field, Float value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min()) && (null != value)) {
+			Float min = Float.parseFloat(checkPersist.min());
+			if (min > value) {
+				throw new Exception("check persist floatValue min error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not lesser then:" + checkPersist.min() + ".");
+			}
+		}
+	}
+}

+ 80 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/IntegerValueListPersistChecker.java

@@ -0,0 +1,80 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.tools.ListTools;
+
+public class IntegerValueListPersistChecker extends AbstractChecker {
+
+	public IntegerValueListPersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, List<Integer> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.allowContainEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.max(field, values, jpa, checkPersist, checkPersistType);
+			this.min(field, values, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, List<Integer> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (ListTools.nullToEmpty(values).isEmpty())) {
+			throw new Exception("check persist integerValueList allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or emtpy.");
+		}
+	}
+
+	private void allowContainEmpty(Field field, List<Integer> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (!checkPersist.allowContainEmpty()) {
+			for (Integer o : ListTools.nullToEmpty(values)) {
+				if (null == o) {
+					throw new Exception("check persist integerValueList allowContainEmpty error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", can not contain null.");
+				}
+			}
+		}
+	}
+
+	private void max(Field field, List<Integer> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max())) {
+			Integer max = Integer.parseInt(checkPersist.max());
+			for (Integer o : ListTools.nullToEmpty(values)) {
+				if (null != o && o > max) {
+					throw new Exception("check persist integerValueList max error, class:" + jpa.getClass().getName()
+							+ ", field:" + field.getName() + ", can not contain value larger than:" + checkPersist.max()
+							+ ".");
+				}
+			}
+
+		}
+	}
+
+	private void min(Field field, List<Integer> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min())) {
+			Integer min = Integer.parseInt(checkPersist.min());
+			for (Integer o : ListTools.nullToEmpty(values)) {
+				if (null != o && o < min) {
+					throw new Exception("check persist integerValueList min error, class:" + jpa.getClass().getName()
+							+ ", field:" + field.getName() + ", can not contain value lesser than:" + checkPersist.min()
+							+ ".");
+				}
+			}
+		}
+	}
+}

+ 58 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/IntegerValuePersistChecker.java

@@ -0,0 +1,58 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+
+public class IntegerValuePersistChecker extends AbstractChecker {
+
+	public IntegerValuePersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, Integer value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, value, jpa, checkPersist, checkPersistType);
+			this.max(field, value, jpa, checkPersist, checkPersistType);
+			this.min(field, value, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, Integer value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (null == value)) {
+			throw new Exception("check persist integerValue allowEmpty error, class:" + jpa.getClass().getName() + ", field:"
+					+ field.getName() + ", can not be null.");
+		}
+	}
+
+	private void max(Field field, Integer value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max()) && (null != value)) {
+			Integer max = Integer.parseInt(checkPersist.max());
+			if (max < value) {
+				throw new Exception("check persist integerValue max error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not larger then:" + checkPersist.max() + ".");
+			}
+		}
+	}
+
+	private void min(Field field, Integer value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min()) && (null != value)) {
+			Integer min = Integer.parseInt(checkPersist.min());
+			if (min > value) {
+				throw new Exception("check persist integerValue min error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not lesser then:" + checkPersist.min() + ".");
+			}
+		}
+	}
+}

+ 79 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/LongValueListPersistChecker.java

@@ -0,0 +1,79 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.tools.ListTools;
+
+public class LongValueListPersistChecker extends AbstractChecker {
+
+	public LongValueListPersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, List<Long> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.allowContainEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.max(field, values, jpa, checkPersist, checkPersistType);
+			this.min(field, values, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, List<Long> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (ListTools.nullToEmpty(values).isEmpty())) {
+			throw new Exception("check persist longValueList allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or emtpy.");
+		}
+	}
+
+	private void allowContainEmpty(Field field, List<Long> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (!checkPersist.allowContainEmpty()) {
+			for (Long o : ListTools.nullToEmpty(values)) {
+				if (null == o) {
+					throw new Exception("check persist longValueList allowContainEmpty error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", can not contain null.");
+				}
+			}
+		}
+	}
+
+	private void max(Field field, List<Long> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max())) {
+			Long max = Long.parseLong(checkPersist.max());
+			for (Long o : ListTools.nullToEmpty(values)) {
+				if (null != o && o > max) {
+					throw new Exception("check persist longValueList max error, class:" + jpa.getClass().getName()
+							+ ", field:" + field.getName() + ", can not contain value larger than:" + checkPersist.max()
+							+ ".");
+				}
+			}
+		}
+	}
+
+	private void min(Field field, List<Long> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min())) {
+			Long min = Long.parseLong(checkPersist.min());
+			for (Long o : ListTools.nullToEmpty(values)) {
+				if (null != o && o < min) {
+					throw new Exception("check persist longValueList min error, class:" + jpa.getClass().getName()
+							+ ", field:" + field.getName() + ", can not contain value lesser than:" + checkPersist.min()
+							+ ".");
+				}
+			}
+		}
+	}
+}

+ 58 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/LongValuePersistChecker.java

@@ -0,0 +1,58 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+
+public class LongValuePersistChecker extends AbstractChecker {
+
+	public LongValuePersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, Long value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, value, jpa, checkPersist, checkPersistType);
+			this.max(field, value, jpa, checkPersist, checkPersistType);
+			this.min(field, value, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, Long value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (null == value)) {
+			throw new Exception("check persist longValue allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null.");
+		}
+	}
+
+	private void max(Field field, Long value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.max()) && (null != value)) {
+			Long max = Long.parseLong(checkPersist.max());
+			if (max < value) {
+				throw new Exception("check persist longValue max error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not larger then:" + checkPersist.max() + ".");
+			}
+		}
+	}
+
+	private void min(Field field, Long value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.min()) && (null != value)) {
+			Long min = Long.parseLong(checkPersist.min());
+			if (min > value) {
+				throw new Exception("check persist longValue min error, class:" + jpa.getClass().getName() + ", field:"
+						+ field.getName() + ", can not lesser then:" + checkPersist.min() + ".");
+			}
+		}
+	}
+}

+ 255 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/StringValueListPersistChecker.java

@@ -0,0 +1,255 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.openjpa.persistence.jdbc.ElementColumn;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.entity.annotation.CitationExist;
+import com.x.base.core.entity.annotation.CitationNotExist;
+import com.x.base.core.entity.annotation.Equal;
+import com.x.base.core.entity.annotation.NotEqual;
+import com.x.base.core.entity.tools.JpaObjectTools;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.tools.StringTools;
+
+public class StringValueListPersistChecker extends AbstractChecker {
+	public StringValueListPersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.allowContainEmpty(field, values, jpa, checkPersist, checkPersistType);
+			this.length(field, values, jpa, checkPersist, checkPersistType);
+			this.simply(field, values, jpa, checkPersist, checkPersistType);
+			this.fileName(field, values, jpa, checkPersist, checkPersistType);
+			this.mail(field, values, jpa, checkPersist, checkPersistType);
+			this.moible(field, values, jpa, checkPersist, checkPersistType);
+			this.pattern(field, values, jpa, checkPersist, checkPersistType);
+		}
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.citationOnly)) {
+			this.citationExists(this.emc, field, values, jpa, checkPersist, checkPersistType);
+			this.citationNotExists(this.emc, field, values, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (ListTools.nullToEmpty(values).isEmpty())) {
+			throw new Exception("check persist stirngValueList allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or empty.");
+		}
+	}
+
+	private void allowContainEmpty(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (!checkPersist.allowContainEmpty()) {
+			for (String str : ListTools.nullToEmpty(values)) {
+				if (StringUtils.isEmpty(str)) {
+					throw new Exception("check persist stirngValueList allowContainEmpty error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ",values:"
+							+ StringUtils.join(values, ",") + " can not contain null or empty value.");
+				}
+			}
+		}
+	}
+
+	private void length(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		ElementColumn elementColumn = field.getAnnotation(ElementColumn.class);
+		for (String str : ListTools.nullToEmpty(values)) {
+			if (StringUtils.isNotEmpty(str)) {
+				int len = Objects.toString(str).getBytes(Charset.forName("UTF-8")).length;
+				if (len > elementColumn.length()) {
+					throw new Exception("check persist stirngValueList length error, class:" + jpa.getClass().getName()
+							+ ", field:" + field.getName() + ", values:" + StringUtils.join(values, ",") + ",value:"
+							+ str + ", length:" + len + ", max:" + elementColumn.length() + ".");
+				}
+			}
+		}
+	}
+
+	private void simply(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (checkPersist.simplyString()) {
+			for (String str : ListTools.nullToEmpty(values)) {
+				if (StringUtils.isNotEmpty(str)) {
+					if (!StringTools.isSimply(str)) {
+						throw new Exception("check persist stringValueList simply error, class:"
+								+ jpa.getClass().getName() + ", field:" + field.getName() + ", values:"
+								+ StringUtils.join(values, ",") + "value:" + str + ".");
+					}
+				}
+			}
+		}
+	}
+
+	private void fileName(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (checkPersist.fileNameString()) {
+			for (String str : ListTools.nullToEmpty(values)) {
+				if (StringUtils.isNotEmpty(str)) {
+					if (!StringTools.isFileName(str)) {
+						throw new Exception("check persist stringValueList fileName error, class:"
+								+ jpa.getClass().getName() + ", field:" + field.getName() + ", values:"
+								+ StringUtils.join(values, ",") + "value:" + str + ".");
+					}
+				}
+			}
+		}
+	}
+
+	private void mail(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (checkPersist.mailString()) {
+			for (String str : ListTools.nullToEmpty(values)) {
+				if (StringUtils.isNotEmpty(str)) {
+					if (!StringTools.isMail(str)) {
+						throw new Exception("check persist stringValueList mail error, class:"
+								+ jpa.getClass().getName() + ", field:" + field.getName() + ", values:"
+								+ StringUtils.join(values, ",") + ", value:" + str + ".");
+					}
+				}
+			}
+		}
+	}
+
+	private void pattern(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.pattern())) {
+			Pattern pattern = Pattern.compile(checkPersist.pattern());
+			for (String str : ListTools.nullToEmpty(values)) {
+				Matcher matcher = pattern.matcher(str);
+				if (!matcher.find()) {
+					throw new Exception(
+							"check persist stirngValue pattern error, class:" + jpa.getClass().getName() + ", field:"
+									+ field.getName() + ", value:" + str + ", pattern:" + checkPersist.pattern() + ".");
+				}
+			}
+		}
+	}
+
+	private void moible(Field field, List<String> values, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (checkPersist.mobileString()) {
+			for (String str : ListTools.nullToEmpty(values)) {
+				if (StringUtils.isNotEmpty(str)) {
+					if (!StringTools.isMobile(str)) {
+						throw new Exception("check persist stringValueList mobile error, class:"
+								+ jpa.getClass().getName() + ", field:" + field.getName() + ", values:"
+								+ StringUtils.join(values, ",") + "value:" + str + ".");
+					}
+				}
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void citationExists(EntityManagerContainerBasic emc, Field field, List<String> values, JpaObject jpa,
+			CheckPersist checkPersist, CheckPersistType checkPersistType) throws Exception {
+		next: for (String value : ListTools.nullToEmpty(values)) {
+			if (ArrayUtils.contains(checkPersist.excludes(), value)) {
+				continue next;
+			}
+			for (CitationExist citationExist : checkPersist.citationExists()) {
+				EntityManager em = emc.get(citationExist.type());
+				CriteriaBuilder cb = em.getCriteriaBuilder();
+				CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+				Root<? extends JpaObject> root = cq.from(citationExist.type());
+				Predicate p = cb.disjunction();
+				for (String str : citationExist.fields()) {
+					/* 如果值过长db2会报错 302 22001 */
+					if (JpaObjectTools.withinDefinedLength(value, citationExist.type(), str)) {
+						Path<?> path = root.get(str);
+						if (JpaObjectTools.isList(path)) {
+							p = cb.or(p, cb.isMember(value, (Path<List<String>>) path));
+						} else {
+							p = cb.or(p, cb.equal(path, value));
+						}
+					}
+				}
+				p = cb.and(p, cb.notEqual(root.get("id"), jpa.getId()));
+				for (Equal o : citationExist.equals()) {
+					p = cb.and(p, cb.equal(root.get(o.field()), jpa.get(o.property())));
+				}
+				for (NotEqual o : citationExist.notEquals()) {
+					p = cb.and(p, cb.notEqual(root.get(o.field()), jpa.get(o.property())));
+				}
+				cq.select(cb.count(root)).where(p);
+				Long count = em.createQuery(cq).getSingleResult();
+				if (count == 0) {
+					throw new Exception("check persist stringValueList citationExists error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", values: "
+							+ StringUtils.join(values, ",") + ", value:" + value + ", must be a existed in class:"
+							+ citationExist.type() + ", fields:" + StringUtils.join(citationExist.fields(), ",") + ".");
+				}
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void citationNotExists(EntityManagerContainerBasic emc, Field field, List<String> values, JpaObject jpa,
+			CheckPersist checkPersist, CheckPersistType checkPersistType) throws Exception {
+		next: for (String value : ListTools.nullToEmpty(values)) {
+			if (ArrayUtils.contains(checkPersist.excludes(), value)) {
+				continue next;
+			}
+			for (CitationNotExist citationNotExist : checkPersist.citationNotExists()) {
+				EntityManager em = emc.get(citationNotExist.type());
+				CriteriaBuilder cb = em.getCriteriaBuilder();
+				CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+				Root<? extends JpaObject> root = cq.from(citationNotExist.type());
+				Predicate p = cb.disjunction();
+				for (String str : citationNotExist.fields()) {
+					/* 如果值过长db2会报错 302 22001 */
+					if (JpaObjectTools.withinDefinedLength(value, citationNotExist.type(), str)) {
+						Path<?> path = root.get(str);
+						if (JpaObjectTools.isList(path)) {
+							p = cb.or(p, cb.isMember(value, (Path<List<String>>) path));
+						} else {
+							p = cb.or(p, cb.equal(path, value));
+						}
+					}
+				}
+				p = cb.and(p, cb.notEqual(root.get("id"), jpa.getId()));
+				for (Equal o : citationNotExist.equals()) {
+					p = cb.and(p, cb.equal(root.get(o.field()), jpa.get(o.property())));
+				}
+				for (NotEqual o : citationNotExist.notEquals()) {
+					p = cb.and(p, cb.notEqual(root.get(o.field()), jpa.get(o.property())));
+				}
+				cq.select(cb.count(root)).where(p);
+				Long count = em.createQuery(cq).getSingleResult();
+				if (count != 0) {
+					throw new Exception(
+							"check persist stringValueList citationNotExists error, class:" + jpa.getClass().getName()
+									+ ", field:" + field.getName() + ", values: " + StringUtils.join(values, ",")
+									+ ", value:" + value + ", already existed in class:" + citationNotExist.type()
+									+ ", fields:" + StringUtils.join(citationNotExist.fields(), ",") + ".");
+				}
+			}
+		}
+	}
+}

+ 121 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/StringValueListRemoveChecker.java

@@ -0,0 +1,121 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Objects;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckRemove;
+import com.x.base.core.entity.annotation.CheckRemoveType;
+import com.x.base.core.entity.annotation.CitationExist;
+import com.x.base.core.entity.annotation.CitationNotExist;
+import com.x.base.core.entity.annotation.Equal;
+import com.x.base.core.entity.annotation.NotEqual;
+import com.x.base.core.entity.tools.JpaObjectTools;
+import com.x.base.core.project.tools.ListTools;
+
+public class StringValueListRemoveChecker extends AbstractChecker {
+	public StringValueListRemoveChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, List<String> values, JpaObject jpa, CheckRemove checkRemove,
+			CheckRemoveType checkRemoveType) throws Exception {
+		if (Objects.equals(checkRemoveType, CheckRemoveType.all)) {
+			this.citationExists(this.emc, field, values, jpa, checkRemove, checkRemoveType);
+			this.citationNotExists(this.emc, field, values, jpa, checkRemove, checkRemoveType);
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void citationExists(EntityManagerContainerBasic emc, Field field, List<String> values, JpaObject jpa,
+			CheckRemove checkRemove, CheckRemoveType checkRemoveType) throws Exception {
+		next: for (String value : ListTools.nullToEmpty(values)) {
+			if (ArrayUtils.contains(checkRemove.excludes(), value)) {
+				continue next;
+			}
+			for (CitationExist citationExist : checkRemove.citationExists()) {
+				EntityManager em = emc.get(citationExist.type());
+				CriteriaBuilder cb = em.getCriteriaBuilder();
+				CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+				Root<? extends JpaObject> root = cq.from(citationExist.type());
+				Predicate p = cb.disjunction();
+				for (String str : citationExist.fields()) {
+					Path<?> path = root.get(str);
+					if (JpaObjectTools.isList(path)) {
+						p = cb.or(p, cb.isMember(value, (Path<List<String>>) path));
+					} else {
+						p = cb.or(p, cb.equal(path, value));
+					}
+				}
+				p = cb.and(p, cb.notEqual(root.get("id"), jpa.getId()));
+				for (Equal o : citationExist.equals()) {
+					p = cb.and(p, cb.equal(root.get(o.field()), jpa.get(o.property())));
+				}
+				for (NotEqual o : citationExist.notEquals()) {
+					p = cb.and(p, cb.notEqual(root.get(o.field()), jpa.get(o.property())));
+				}
+				cq.select(cb.count(root)).where(p);
+				Long count = em.createQuery(cq).getSingleResult();
+				if (count == 0) {
+					throw new Exception("check remove stringValueList citationExists error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", values: "
+							+ StringUtils.join(values, ",") + ", value:" + value + ", must be a existed in class:"
+							+ citationExist.type() + ", fields:" + StringUtils.join(citationExist.fields(), ",") + ".");
+				}
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void citationNotExists(EntityManagerContainerBasic emc, Field field, List<String> values, JpaObject jpa,
+			CheckRemove checkRemove, CheckRemoveType checkRemoveType) throws Exception {
+		next: for (String value : ListTools.nullToEmpty(values)) {
+			if (ArrayUtils.contains(checkRemove.excludes(), value)) {
+				continue next;
+			}
+			for (CitationNotExist citationNotExist : checkRemove.citationNotExists()) {
+				EntityManager em = emc.get(citationNotExist.type());
+				CriteriaBuilder cb = em.getCriteriaBuilder();
+				CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+				Root<? extends JpaObject> root = cq.from(citationNotExist.type());
+				Predicate p = cb.disjunction();
+				for (String str : citationNotExist.fields()) {
+					Path<?> path = root.get(str);
+					if (JpaObjectTools.isList(path)) {
+						p = cb.or(p, cb.isMember(value, (Path<List<String>>) path));
+					} else {
+						p = cb.or(p, cb.equal(path, value));
+					}
+				}
+				p = cb.and(p, cb.notEqual(root.get("id"), jpa.getId()));
+				for (Equal o : citationNotExist.equals()) {
+					p = cb.and(p, cb.equal(root.get(o.field()), jpa.get(o.property())));
+				}
+				for (NotEqual o : citationNotExist.notEquals()) {
+					p = cb.and(p, cb.notEqual(root.get(o.field()), jpa.get(o.property())));
+				}
+				cq.select(cb.count(root)).where(p);
+				Long count = em.createQuery(cq).getSingleResult();
+				if (count != 0) {
+					throw new Exception(
+							"check remove stringValueList citationNotExists error, class:" + jpa.getClass().getName()
+									+ ", field:" + field.getName() + ", values: " + StringUtils.join(values, ",")
+									+ ", value:" + value + ", already existed in class:" + citationNotExist.type()
+									+ ", fields:" + StringUtils.join(citationNotExist.fields(), ",") + ".");
+				}
+			}
+		}
+	}
+}

+ 202 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/StringValuePersistChecker.java

@@ -0,0 +1,202 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.persistence.Column;
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.entity.annotation.CitationExist;
+import com.x.base.core.entity.annotation.CitationNotExist;
+import com.x.base.core.entity.annotation.Equal;
+import com.x.base.core.entity.annotation.NotEqual;
+import com.x.base.core.entity.tools.JpaObjectTools;
+import com.x.base.core.project.tools.StringTools;
+
+public class StringValuePersistChecker extends AbstractChecker {
+
+	public StringValuePersistChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, String value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.baseOnly)) {
+			this.allowEmpty(field, value, jpa, checkPersist, checkPersistType);
+			this.length(field, value, jpa, checkPersist, checkPersistType);
+			this.simply(field, value, jpa, checkPersist, checkPersistType);
+			this.fileName(field, value, jpa, checkPersist, checkPersistType);
+			this.mail(field, value, jpa, checkPersist, checkPersistType);
+			this.mobile(field, value, jpa, checkPersist, checkPersistType);
+			this.pattern(field, value, jpa, checkPersist, checkPersistType);
+		}
+		if (Objects.equals(checkPersistType, CheckPersistType.all)
+				|| Objects.equals(checkPersistType, CheckPersistType.citationOnly)) {
+			this.citationExists(this.emc, field, value, jpa, checkPersist, checkPersistType);
+			this.citationNotExists(this.emc, field, value, jpa, checkPersist, checkPersistType);
+		}
+	}
+
+	private void allowEmpty(Field field, String value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if ((!checkPersist.allowEmpty()) && (value == null || value.toString().length() < 1)) {
+			throw new Exception("check persist stirngValue allowEmpty error, class:" + jpa.getClass().getName()
+					+ ", field:" + field.getName() + ", can not be null or empty.");
+		}
+	}
+
+	private void length(Field field, String value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		Column column = field.getAnnotation(Column.class);
+		int len = Objects.toString(value).getBytes(Charset.forName("UTF-8")).length;
+		if (len > column.length()) {
+			throw new Exception("check persist stirngValue length error, class:" + jpa.getClass().getName() + ", field:"
+					+ field.getName() + ", value:" + value + ", length:" + len + ", max:" + column.length() + ".");
+		}
+	}
+
+	private void simply(Field field, String value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (checkPersist.simplyString() && StringUtils.isNotEmpty(value)) {
+			if (!StringTools.isSimply(value)) {
+				throw new Exception("check persist stirngValue simply error, class:" + jpa.getClass().getName()
+						+ ", field:" + field.getName() + ", value:" + value + ".");
+			}
+		}
+	}
+
+	private void fileName(Field field, String value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (checkPersist.fileNameString() && StringUtils.isNotEmpty(value)) {
+			if (!StringTools.isFileName(value)) {
+				throw new Exception("check persist stirngValue fileName error, class:" + jpa.getClass().getName()
+						+ ", field:" + field.getName() + ", value:" + value + ".");
+			}
+		}
+	}
+
+	private void mail(Field field, String value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (checkPersist.mailString() && StringUtils.isNotEmpty(value)) {
+			if (!StringTools.isMail(value)) {
+				throw new Exception("check persist stirngValue mail error, class:" + jpa.getClass().getName()
+						+ ", field:" + field.getName() + ", value:" + value + ".");
+			}
+		}
+	}
+
+	private void mobile(Field field, String value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (checkPersist.mobileString() && StringUtils.isNotEmpty(value)) {
+			if (!StringTools.isMobile(value)) {
+				throw new Exception("check persist stirngValue mobile error, class:" + jpa.getClass().getName()
+						+ ", field:" + field.getName() + ", value:" + value + ".");
+			}
+
+		}
+	}
+
+	private void pattern(Field field, String value, JpaObject jpa, CheckPersist checkPersist,
+			CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(checkPersist.pattern()) && StringUtils.isNotEmpty(value)) {
+			Pattern pattern = Pattern.compile(checkPersist.pattern());
+			Matcher matcher = pattern.matcher(value);
+			if (!matcher.find()) {
+				throw new Exception(
+						"check persist stirngValue pattern error, class:" + jpa.getClass().getName() + ", field:"
+								+ field.getName() + ", value:" + value + ", pattern:" + checkPersist.pattern() + ".");
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void citationExists(EntityManagerContainerBasic emc, Field field, String value, JpaObject jpa,
+			CheckPersist checkPersist, CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(value) && (!ArrayUtils.contains(checkPersist.excludes(), value))) {
+			for (CitationExist citationExist : checkPersist.citationExists()) {
+				EntityManager em = emc.get(citationExist.type());
+				CriteriaBuilder cb = em.getCriteriaBuilder();
+				CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+				Root<? extends JpaObject> root = cq.from(citationExist.type());
+				Predicate p = cb.disjunction();
+				for (String str : citationExist.fields()) {
+					Path<?> path = root.get(str);
+					if (JpaObjectTools.isList(path)) {
+						p = cb.or(p, cb.isMember(value, (Path<List<String>>) path));
+					} else {
+						p = cb.or(p, cb.equal(path, value));
+					}
+				}
+				p = cb.and(p, cb.notEqual(root.get("id"), jpa.getId()));
+				for (Equal o : citationExist.equals()) {
+					p = cb.and(p, cb.equal(root.get(o.field()), jpa.get(o.property())));
+				}
+				for (NotEqual o : citationExist.notEquals()) {
+					p = cb.and(p, cb.notEqual(root.get(o.field()), jpa.get(o.property())));
+				}
+				cq.select(cb.count(root)).where(p);
+				Long count = em.createQuery(cq).getSingleResult();
+				if (count == 0) {
+					throw new Exception("check persist stirngValue citationExists error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", value: " + value
+							+ " must be a existed in class:" + citationExist.type() + ", fields:"
+							+ StringUtils.join(citationExist.fields(), ",") + ".");
+				}
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void citationNotExists(EntityManagerContainerBasic emc, Field field, String value, JpaObject jpa,
+			CheckPersist checkPersist, CheckPersistType checkPersistType) throws Exception {
+		if (StringUtils.isNotEmpty(value) && (!ArrayUtils.contains(checkPersist.excludes(), value))) {
+			for (CitationNotExist citationNotExist : checkPersist.citationNotExists()) {
+				EntityManager em = emc.get(citationNotExist.type());
+				CriteriaBuilder cb = em.getCriteriaBuilder();
+				CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+				Root<? extends JpaObject> root = cq.from(citationNotExist.type());
+				Predicate p = cb.disjunction();
+				for (String str : citationNotExist.fields()) {
+					Path<?> path = root.get(str);
+					if (JpaObjectTools.isList(path)) {
+						p = cb.or(p, cb.isMember(value, (Path<List<String>>) path));
+					} else {
+						p = cb.or(p, cb.equal(path, value));
+					}
+				}
+				p = cb.and(p, cb.notEqual(root.get("id"), jpa.getId()));
+				for (Equal o : citationNotExist.equals()) {
+					p = cb.and(p, cb.equal(root.get(o.field()), jpa.get(o.property())));
+				}
+				for (NotEqual o : citationNotExist.notEquals()) {
+					p = cb.and(p, cb.notEqual(root.get(o.field()), jpa.get(o.property())));
+				}
+				cq.select(cb.count(root)).where(p);
+				Long count = em.createQuery(cq).getSingleResult();
+				if (count != 0) {
+					throw new Exception("check persist stirngValue citationNotExists error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", value: " + value
+							+ " must be a not existed in class:" + citationNotExist.type() + ", fields:"
+							+ StringUtils.join(citationNotExist.fields(), ",") + ".");
+				}
+			}
+		}
+	}
+}

+ 114 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/checker/StringValueRemoveChecker.java

@@ -0,0 +1,114 @@
+package com.x.base.core.container.checker;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Objects;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainerBasic;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckRemove;
+import com.x.base.core.entity.annotation.CheckRemoveType;
+import com.x.base.core.entity.annotation.CitationExist;
+import com.x.base.core.entity.annotation.CitationNotExist;
+import com.x.base.core.entity.annotation.Equal;
+import com.x.base.core.entity.annotation.NotEqual;
+import com.x.base.core.entity.tools.JpaObjectTools;
+
+public class StringValueRemoveChecker extends AbstractChecker {
+
+	public StringValueRemoveChecker(EntityManagerContainerBasic emc) {
+		super(emc);
+	}
+
+	public void check(Field field, String value, JpaObject jpa, CheckRemove checkRemove,
+			CheckRemoveType checkRemoveType) throws Exception {
+		if (Objects.equals(checkRemoveType, CheckRemoveType.all)) {
+			this.citationExists(this.emc, field, value, jpa, checkRemove, checkRemoveType);
+			this.citationNotExists(this.emc, field, value, jpa, checkRemove, checkRemoveType);
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void citationExists(EntityManagerContainerBasic emc, Field field, String value, JpaObject jpa,
+			CheckRemove checkRemove, CheckRemoveType checkRemoveType) throws Exception {
+		if (StringUtils.isNotEmpty(value) && (!ArrayUtils.contains(checkRemove.excludes(), value))) {
+			for (CitationExist citationExist : checkRemove.citationExists()) {
+				EntityManager em = emc.get(citationExist.type());
+				CriteriaBuilder cb = em.getCriteriaBuilder();
+				CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+				Root<? extends JpaObject> root = cq.from(citationExist.type());
+				Predicate p = cb.disjunction();
+				for (String str : citationExist.fields()) {
+					Path<?> path = root.get(str);
+					if (JpaObjectTools.isList(path)) {
+						p = cb.or(p, cb.isMember(value, (Path<List<String>>) path));
+					} else {
+						p = cb.or(p, cb.equal(path, value));
+					}
+				}
+				p = cb.and(p, cb.notEqual(root.get("id"), jpa.getId()));
+				for (Equal o : citationExist.equals()) {
+					p = cb.and(p, cb.equal(root.get(o.field()), jpa.get(o.property())));
+				}
+				for (NotEqual o : citationExist.notEquals()) {
+					p = cb.and(p, cb.notEqual(root.get(o.field()), jpa.get(o.property())));
+				}
+				cq.select(cb.count(root)).where(p);
+				Long count = em.createQuery(cq).getSingleResult();
+				if (count == 0) {
+					throw new Exception("check remove stirngValue citationExists error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", value: " + value
+							+ " must be a existed in class:" + citationExist.type() + ", fields:"
+							+ StringUtils.join(citationExist.fields(), ",") + ".");
+				}
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void citationNotExists(EntityManagerContainerBasic emc, Field field, String value, JpaObject jpa,
+			CheckRemove checkRemove, CheckRemoveType checkRemoveType) throws Exception {
+		if (StringUtils.isNotEmpty(value) && (!ArrayUtils.contains(checkRemove.excludes(), value))) {
+			for (CitationNotExist citationNotExist : checkRemove.citationNotExists()) {
+				EntityManager em = emc.get(citationNotExist.type());
+				CriteriaBuilder cb = em.getCriteriaBuilder();
+				CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+				Root<? extends JpaObject> root = cq.from(citationNotExist.type());
+				Predicate p = cb.disjunction();
+				for (String str : citationNotExist.fields()) {
+					Path<?> path = root.get(str);
+					if (JpaObjectTools.isList(path)) {
+						p = cb.or(p, cb.isMember(value, (Path<List<String>>) path));
+					} else {
+						p = cb.or(p, cb.equal(path, value));
+					}
+				}
+				p = cb.and(p, cb.notEqual(root.get("id"), jpa.getId()));
+				for (Equal o : citationNotExist.equals()) {
+					p = cb.and(p, cb.equal(root.get(o.field()), jpa.get(o.property())));
+				}
+				for (NotEqual o : citationNotExist.notEquals()) {
+					p = cb.and(p, cb.notEqual(root.get(o.field()), jpa.get(o.property())));
+				}
+				cq.select(cb.count(root)).where(p);
+				Long count = em.createQuery(cq).getSingleResult();
+				if (count != 0) {
+					throw new Exception("check remove stirngValue citationNotExists error, class:"
+							+ jpa.getClass().getName() + ", field:" + field.getName() + ", value: " + value
+							+ " must be a not existed in class:" + citationNotExist.type() + ", fields:"
+							+ StringUtils.join(citationNotExist.fields(), ",") + ".");
+				}
+			}
+		}
+	}
+}

+ 129 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/factory/EntityManagerContainerFactory.java

@@ -0,0 +1,129 @@
+package com.x.base.core.container.factory;
+
+import java.lang.reflect.Field;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckRemove;
+import com.x.base.core.project.config.DataMappings;
+
+public class EntityManagerContainerFactory extends SliceEntityManagerContainerFactory {
+
+	private volatile static EntityManagerContainerFactory instance;
+
+	public static void init(String webApplicationDirectory, DataMappings dataMappings) throws Exception {
+		synchronized (EntityManagerContainerFactory.class) {
+			if (instance != null) {
+				EntityManagerContainerFactory.close();
+			}
+			instance = new EntityManagerContainerFactory(webApplicationDirectory, dataMappings);
+		}
+	}
+
+	public static void init(String source) throws Exception {
+		synchronized (EntityManagerContainerFactory.class) {
+			if (instance != null) {
+				EntityManagerContainerFactory.close();
+			}
+			instance = new EntityManagerContainerFactory(source);
+		}
+	}
+
+	public static void init() throws Exception {
+		synchronized (EntityManagerContainerFactory.class) {
+			if (instance != null) {
+				EntityManagerContainerFactory.close();
+			}
+			instance = new EntityManagerContainerFactory("");
+		}
+	}
+
+	public static EntityManagerContainerFactory instance() throws Exception {
+		if (instance == null) {
+			throw new Exception("get EntityManagerContainerFactory instance error, not initial.");
+		}
+		return instance;
+	}
+
+	private EntityManagerContainerFactory(String webApplicationDirectory, DataMappings dataMappings) throws Exception {
+		super(webApplicationDirectory, dataMappings);
+	}
+
+	private EntityManagerContainerFactory(String source) throws Exception {
+		super(source);
+	}
+
+	public static void close() throws Exception {
+		try {
+			if (instance != null) {
+				for (EntityManagerFactory emf : instance.entityManagerFactoryMap.values()) {
+					if (emf.isOpen()) {
+						emf.close();
+					}
+				}
+				instance.entityManagerFactoryMap.clear();
+				instance.checkPersistFieldMap.clear();
+				instance.checkRemoveFieldMap.clear();
+			}
+			/* 注销驱动程序 */
+			// Set<Driver> drivers = new HashSet<>();
+			// for (String url : instance.jdbcUrls) {
+			// drivers.add(DriverManager.getDriver(url));
+			// }
+			Enumeration<Driver> drivers = DriverManager.getDrivers();
+			while (drivers.hasMoreElements()) {
+				Driver driver = drivers.nextElement();
+				// System.out.println("deregisterDriver:" + driver);
+				DriverManager.deregisterDriver(driver);
+			}
+			/* 由于可能重新载入 */
+			instance = null;
+		} catch (Exception e) {
+			throw new Exception("close error.", e);
+		}
+	}
+
+	public EntityManagerContainer create() {
+		EntityManagerContainer container = new EntityManagerContainer(this);
+		return container;
+	}
+
+	public <T extends JpaObject> EntityManager createEntityManager(Class<T> cls) throws Exception {
+		try {
+			for (Class<?> clazz : entityManagerFactoryMap.keySet()) {
+				if (clazz.isAssignableFrom(cls)) {
+					return entityManagerFactoryMap.get(clazz).createEntityManager();
+				}
+			}
+			throw new Exception("can not createEntityManager for class " + cls.getName()
+					+ ", not registed in EntityManagerContainerFactory.");
+		} catch (Exception e) {
+			throw new Exception("get entityManager for " + cls + " error.", e);
+		}
+	}
+
+	public Map<Field, CheckPersist> getCheckPersistFields(Class<?> clazz) throws Exception {
+		return checkPersistFieldMap.get(assignableFrom(clazz));
+	}
+
+	public Map<Field, CheckRemove> getCheckRemoveFields(Class<?> clazz) throws Exception {
+		return checkRemoveFieldMap.get(assignableFrom(clazz));
+	}
+
+	public List<Field> getFlagFields(Class<?> clazz) throws Exception {
+		return flagMap.get(assignableFrom(clazz));
+	}
+
+	public List<Field> getRestrictFlagFields(Class<?> clazz) throws Exception {
+		return restrictFlagMap.get(assignableFrom(clazz));
+	}
+}

+ 182 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/factory/SliceEntityManagerContainerFactory.java

@@ -0,0 +1,182 @@
+package com.x.base.core.container.factory;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Id;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.PersistenceProductDerivation;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.XMLWriter;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CheckRemove;
+import com.x.base.core.entity.annotation.Flag;
+import com.x.base.core.entity.annotation.RestrictFlag;
+import com.x.base.core.project.config.DataMappings;
+
+public abstract class SliceEntityManagerContainerFactory {
+
+	protected static String persistence_xml_path = "META-INF/x_persistence.xml";
+
+	/* class 与 entityManagerFactory 映射表 */
+	protected Map<Class<? extends JpaObject>, EntityManagerFactory> entityManagerFactoryMap = new ConcurrentHashMap<Class<? extends JpaObject>, EntityManagerFactory>();
+	/* class 与 @Flag字段 映射表 */
+	protected Map<Class<? extends JpaObject>, List<Field>> flagMap = new ConcurrentHashMap<Class<? extends JpaObject>, List<Field>>();
+	/* class 与 entityManagerFactory 映射表 */
+	protected Map<Class<? extends JpaObject>, List<Field>> restrictFlagMap = new ConcurrentHashMap<Class<? extends JpaObject>, List<Field>>();
+	/* class 与 class 中需要检查 Persist 字段的对应表 */
+	protected Map<Class<? extends JpaObject>, Map<Field, CheckPersist>> checkPersistFieldMap = new ConcurrentHashMap<Class<? extends JpaObject>, Map<Field, CheckPersist>>();
+	/* class 与 class 中需要检查 Remove 字段的对应表 */
+	protected Map<Class<? extends JpaObject>, Map<Field, CheckRemove>> checkRemoveFieldMap = new ConcurrentHashMap<Class<? extends JpaObject>, Map<Field, CheckRemove>>();
+
+	protected SliceEntityManagerContainerFactory(String webApplicationDirectory, DataMappings dataMappings)
+			throws Exception {
+		Set<Class<? extends JpaObject>> classes = mergePersistenceXml(webApplicationDirectory, dataMappings);
+		for (Class<? extends JpaObject> clz : classes) {
+			checkPersistFieldMap.put(clz, this.loadCheckPersistField(clz));
+			checkRemoveFieldMap.put(clz, loadCheckRemoveField(clz));
+			entityManagerFactoryMap.put(clz,
+					OpenJPAPersistence.createEntityManagerFactory(clz.getCanonicalName(), persistence_xml_path));
+			flagMap.put(clz, new ArrayList<Field>());
+			restrictFlagMap.put(clz, new ArrayList<Field>());
+			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, Id.class)) {
+				flagMap.get(clz).add(o);
+				restrictFlagMap.get(clz).add(o);
+			}
+			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, Flag.class)) {
+				flagMap.get(clz).add(o);
+				restrictFlagMap.get(clz).add(o);
+			}
+			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, RestrictFlag.class)) {
+				restrictFlagMap.get(clz).add(o);
+			}
+		}
+	}
+
+	protected SliceEntityManagerContainerFactory(String source) throws Exception {
+		Set<Class<? extends JpaObject>> classes = this.listUitClass(source);
+		for (Class<? extends JpaObject> clz : classes) {
+			checkPersistFieldMap.put(clz, this.loadCheckPersistField(clz));
+			checkRemoveFieldMap.put(clz, loadCheckRemoveField(clz));
+			entityManagerFactoryMap.put(clz,
+					OpenJPAPersistence.createEntityManagerFactory(clz.getCanonicalName(), source));
+		}
+	}
+
+	/** 扫描受管实体,生成 x_perisitence.xml */
+	@SuppressWarnings("unchecked")
+	private Set<Class<? extends JpaObject>> mergePersistenceXml(String webApplicationDirectory,
+			DataMappings dataMappings) throws Exception {
+		String name = null;
+		try {
+			Set<Class<? extends JpaObject>> classes = new HashSet<>();
+			File file = new File(webApplicationDirectory + "/WEB-INF/classes/" + persistence_xml_path);
+			SAXReader reader = new SAXReader();
+			Document document = reader.read(file);
+			for (Object o : document.getRootElement().elements("persistence-unit")) {
+				Element unit = (Element) o;
+				name = unit.attribute("name").getValue();
+				// System.out.println("try to load entity class:" + name);
+				Element properties = unit.element("properties");
+				if (null != properties) {
+					properties.clearContent();
+				} else {
+					properties = unit.addElement("properties");
+				}
+				for (Entry<String, String> entry : SlicePropertiesBuilder.getPropertiesDBCP(dataMappings.get(name))
+						.entrySet()) {
+					Element property = properties.addElement("property");
+					property.addAttribute("name", entry.getKey());
+					property.addAttribute("value", entry.getValue());
+				}
+				classes.add((Class<JpaObject>) Class.forName(name));
+			}
+			OutputFormat format = OutputFormat.createPrettyPrint();
+			format.setEncoding("UTF-8");
+			XMLWriter writer = new XMLWriter(new FileWriter(file), format);
+			writer.write(document);
+			writer.close();
+			return classes;
+		} catch (Exception e) {
+			throw new Exception("registContainerEntity error.className:" + name, e);
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	public <T> Class<T> assignableFrom(Class<T> cls) throws Exception {
+		for (Class<?> clazz : this.entityManagerFactoryMap.keySet()) {
+			if (clazz.isAssignableFrom(cls)) {
+				return (Class<T>) clazz;
+			}
+		}
+		throw new Exception("can not find jpa assignable class for " + cls + ".");
+	}
+
+	private <T extends JpaObject> Map<Field, CheckPersist> loadCheckPersistField(Class<T> cls) throws Exception {
+		Map<Field, CheckPersist> map = new HashMap<Field, CheckPersist>();
+		for (Field fld : cls.getDeclaredFields()) {
+			CheckPersist checkPersist = fld.getAnnotation(CheckPersist.class);
+			if (null != checkPersist) {
+				map.put(fld, checkPersist);
+			}
+
+		}
+		return map;
+	}
+
+	private <T extends JpaObject> Map<Field, CheckRemove> loadCheckRemoveField(Class<T> cls) throws Exception {
+		Map<Field, CheckRemove> map = new HashMap<Field, CheckRemove>();
+		for (Field fld : cls.getDeclaredFields()) {
+			CheckRemove checkRemove = fld.getAnnotation(CheckRemove.class);
+			if (null != checkRemove) {
+				map.put(fld, checkRemove);
+			}
+		}
+		return map;
+	}
+
+	private Set<Class<? extends JpaObject>> listUitClass(String source) throws Exception {
+		try {
+			Set<Class<? extends JpaObject>> classes = new HashSet<>();
+			URL url;
+			if (StringUtils.isEmpty(source)) {
+				url = this.getClass().getClassLoader().getResource(PersistenceProductDerivation.RSRC_DEFAULT);
+			} else {
+				url = this.getClass().getClassLoader().getResource(source);
+			}
+			if (null == url) {
+				throw new Exception("can not load resource: " + source + ".");
+			}
+			File file = new File(url.toURI());
+			SAXReader reader = new SAXReader();
+			Document document = reader.read(file);
+			for (Object o : document.getRootElement().elements("persistence-unit")) {
+				Element unit = (Element) o;
+				classes.add((Class<JpaObject>) Class.forName(unit.attribute("name").getValue()));
+			}
+			return classes;
+		} catch (Exception e) {
+			throw new Exception("list unit error:" + source, e);
+		}
+	}
+
+}

+ 318 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/container/factory/SlicePropertiesBuilder.java

@@ -0,0 +1,318 @@
+package com.x.base.core.container.factory;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.x.base.core.container.FactorDistributionPolicy;
+import com.x.base.core.project.config.DataMapping;
+
+public class SlicePropertiesBuilder {
+
+	// 20160127要做的事情,删除应用要删除数据字典和work,目前已经删除了信泰的数据字典重复部分,没有来得及删除数据
+
+	public static String driver_db2 = "com.ibm.db2.jcc.DB2Driver";
+	public static String driver_oracle = "oracle.jdbc.OracleDriver";
+	public static String driver_mysql = "com.mysql.jdbc.Driver";
+	public static String driver_postgresql = "org.postgresql.Driver";
+	public static String driver_informix = "com.informix.jdbc.IfxDriver";
+	public static String driver_h2 = "org.h2.Driver";
+	public static String driver_dm = "dm.jdbc.driver.DmDriver";
+	public static String driver_sqlserver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
+	/** 避免db2在aix版本和lwl版本字段长度不一致的问题 */
+	private static String dictionary_db2 = "db2(createPrimaryKeys=false,characterColumnSize=255,maxColumnNameLength=128,maxIndexNameLength=128,maxConstraintNameLength=128)";
+	private static String dictionary_oracle = "oracle(maxTableNameLength=128,maxColumnNameLength=128,maxIndexNameLength=128,maxConstraintNameLength=128,maxEmbeddedClobSize=104857600)";
+	private static String dictionary_mysql = "mysql(clobTypeName=LONGTEXT,blobTypeName=LONGBLOB,createPrimaryKeys=false,maxIndexesPerTable=64)";
+	private static String dictionary_postgresql = "postgres";
+	private static String dictionary_informix = "informix";
+	private static String dictionary_h2 = "org.apache.openjpa.jdbc.sql.H2Dictionary";
+	private static String dictionary_dm = "com.x.base.core.openjpa.jdbc.sql.DMDictionary";
+	private static String dictionary_sqlserver = "sqlserver(schemaCase=preserve)";
+
+	private static String validationQuery_db2 = "select 1 from sysibm.sysdummy1";
+	private static String validationQuery_oracle = "select 1 from dual";
+	private static String validationQuery_mysql = "select 1";
+	private static String validationQuery_postgresql = "select 1";
+	private static String validationQuery_informix = "select 1";
+	private static String validationQuery_h2 = "select 1";
+	private static String validationQuery_dm = "select getdate()";
+	private static String validationQuery_sqlserver = "select 1";
+
+	public static Map<String, String> getPropertiesDBCP(List<DataMapping> list) throws Exception {
+		try {
+			if (list.isEmpty()) {
+				throw new Exception("parameter data list is empty.");
+			}
+			Map<String, String> properties = new LinkedHashMap<String, String>();
+			properties.put("openjpa.BrokerFactory", "slice");
+			properties.put("openjpa.jdbc.DBDictionary", determineDBDictionary(list.get(0)));
+			/**
+			 * 如果是DB2 添加 Schema,mysql 不需要Schema 如果用了Schema H2数据库就会报错说没有Schema
+			 */
+			if (StringUtils.equals(determineDBDictionary(list.get(0)), dictionary_db2)) {
+				properties.put("openjpa.jdbc.Schema", "x");
+			}
+			if (StringUtils.equals(determineDBDictionary(list.get(0)), dictionary_informix)) {
+				properties.put("openjpa.jdbc.Schema", "x");
+			}
+			properties.put("openjpa.slice.Lenient", "false");
+			// properties.put("openjpa.Multithreaded", "true");
+			properties.put("openjpa.slice.DistributionPolicy", FactorDistributionPolicy.class.getName());
+			properties.put("openjpa.slice.Names", getSliceNames(list));
+			// properties.put("openjpa.ConnectionDriverName",
+			// org.apache.commons.dbcp2.BasicDataSource.class.getName());
+			properties.put("openjpa.ConnectionDriverName", DruidDataSource.class.getName());
+			// properties.put("openjpa.ConnectionDriverName",
+			// org.apache.commons.dbcp2.managed.BasicManagedDataSource.class.getCanonicalName());
+			properties.put("openjpa.QueryCompilationCache", "false");
+			properties.put("openjpa.IgnoreChanges", "true");
+			properties.put("openjpa.QueryCache", "false");
+			properties.put("openjpa.jdbc.ResultSetType", "scroll-insensitive");
+			// properties.put("openjpa.DynamicEnhancementAgent", "true");
+			properties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=false)");
+			// properties.put("openjpa.jdbc.SchemaFactory",
+			// "native(ForeignKeys=false)");
+			// properties.put("openjpa.Compatibility",
+			// "StrictIdentityValues=true");
+			/* 事务管理 */
+			// properties.put("openjpa.ManagedRuntime",
+			// "jndi(TransactionManagerName=java:/TransactionManager)");
+			/* 锁 */
+			properties.put("openjpa.LockManager", "none");
+			properties.put("openjpa.Log", "DefaultLevel=WARN");
+			for (int i = 0; i < list.size(); i++) {
+				String slice = getName(i);
+				DataMapping dataMapping = list.get(i);
+				properties.put("openjpa.slice." + slice + ".ConnectionProperties",
+						getConnectionPropertiesDruid(dataMapping));
+				// properties.put("openjpa.slice." + slice +
+				// ".ConnectionDriverName",
+				// org.apache.commons.dbcp.BasicDataSource.class.getCanonicalName());
+				properties.put("openjpa.slice." + slice + ".ConnectionDriverName", DruidDataSource.class.getName());
+				// properties.put("openjpa.slice." + slice +
+				// ".ConnectionDriverName",
+				// org.apache.commons.dbcp2.managed.BasicManagedDataSource.class.getCanonicalName());
+				properties.put("openjpa.slice." + slice + ".Log", getLog(dataMapping));
+				properties.put("openjpa.slice." + slice + ".IgnoreChanges", "true");
+				properties.put("openjpa.slice." + slice + ".QueryCache", "false");
+				properties.put("openjpa.slice." + slice + ".QueryCompilationCache", "false");
+				properties.put("openjpa.slice." + slice + ".LockManager", "none");
+				properties.put("openjpa.slice." + slice + ".ConnectionFactoryProperties",
+						"PrettyPrint=true, PrettyPrintLineLength=72");
+			}
+			return properties;
+		} catch (Exception e) {
+			throw new Exception("can not convert connection to slice properties", e);
+		}
+	}
+
+	// openjpa.slice.Names 属性值
+	public static String getSliceNames(List<DataMapping> list) throws Exception {
+		try {
+			String[] arr = new String[list.size()];
+			for (int j = 0; j < list.size(); j++) {
+				arr[j] = getName(j);
+			}
+			return StringUtils.join(arr, ", ");
+		} catch (Exception e) {
+			throw new Exception("can not create slice names", e);
+		}
+	}
+
+	// 单个slice名称
+	public static String getName(Integer i) throws Exception {
+		try {
+			return "s" + ((1001 + i) + "").substring(1);
+		} catch (Exception e) {
+			throw new Exception("can not create slice name property", e);
+		}
+	}
+
+	// /* 使用DBCP连接池时产生的属性 */
+	// protected static String getConnectionPropertiesDBCP(DataMapping dataMapping)
+	// throws Exception {
+	// try {
+	// String str = "MaxActive=5, MaxIdle=1, MinIdle=0, MaxWait=10000, Username=" +
+	// dataMapping.getUsername()
+	// + ", Password=" + dataMapping.getPassword() + ", TestOnBorrow=true";
+	// if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_db2)) {
+	// str += ", driverClassName=" + driver_db2 + ", url=" + dataMapping.getUrl();
+	// } else if (StringUtils.equals(determineDBDictionary(dataMapping),
+	// dictionary_mysql)) {
+	// String url = dataMapping.getUrl();
+	// // url += "?autoReconnect=true";
+	// str += ", driverClassName=" + driver_mysql + ", url=" + url;
+	// } else if (StringUtils.equals(determineDBDictionary(dataMapping),
+	// dictionary_postgresql)) {
+	// String url = dataMapping.getUrl();
+	// str += ", driverClassName=" + driver_postgresql + ", url=" + url;
+	// } else if (StringUtils.equals(determineDBDictionary(dataMapping),
+	// dictionary_informix)) {
+	// String url = dataMapping.getUrl();
+	// str += ", driverClassName=" + driver_informix + ", url=" + url;
+	// } else if (StringUtils.equals(determineDBDictionary(dataMapping),
+	// dictionary_h2)) {
+	// String url = dataMapping.getUrl();
+	// str += ", driverClassName=" + driver_h2 + ", url=" + url;
+	// }
+	// return str;
+	// } catch (Exception e) {
+	// throw new Exception("can not create connection properites", e);
+	// }
+	// }
+
+	/* 使用DBCP2连接池时产生的属性 */
+	protected static String getConnectionPropertiesDBCP2(DataMapping dataMapping) throws Exception {
+		try {
+			String str = "maxTotal=5, maxIdle=2, minIdle=0, maxWaitMillis=30000, timeBetweenEvictionRunsMillis=300000, minEvictableIdleTimeMillis=300000, maxConnLifetimeMillis=1200000, Username="
+					+ dataMapping.getUsername() + ", Password=" + dataMapping.getPassword();
+			if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_db2)) {
+				str += ",validationQuery=" + validationQuery_db2 + ", driverClassName=" + driver_db2 + ", url="
+						+ dataMapping.getUrl();
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_oracle)) {
+				String url = dataMapping.getUrl();
+				str += ",validationQuery=" + validationQuery_oracle + ", driverClassName=" + driver_oracle + ", url="
+						+ url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_mysql)) {
+				String url = dataMapping.getUrl();
+				// url += "?autoReconnect=true";
+				str += ",validationQuery=" + validationQuery_mysql + ", driverClassName=" + driver_mysql + ", url="
+						+ url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_postgresql)) {
+				String url = dataMapping.getUrl();
+				str += ",validationQuery=" + validationQuery_postgresql + ", driverClassName=" + driver_postgresql
+						+ ", url=" + url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_informix)) {
+				String url = dataMapping.getUrl();
+				str += ",validationQuery=" + validationQuery_informix + ", driverClassName=" + driver_informix
+						+ ", url=" + url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_h2)) {
+				String url = dataMapping.getUrl();
+				str += ",validationQuery=" + validationQuery_h2 + ", driverClassName=" + driver_h2 + ", url=" + url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_dm)) {
+				String url = dataMapping.getUrl();
+				str += ",validationQuery=" + validationQuery_oracle + ", driverClassName=" + driver_dm + ", url=" + url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_sqlserver)) {
+				String url = dataMapping.getUrl();
+				str += ",validationQuery=" + validationQuery_sqlserver + ", driverClassName=" + driver_sqlserver
+						+ ", url=" + url;
+			}
+			return str;
+		} catch (Exception e) {
+			throw new Exception("can not create connection properites", e);
+		}
+	}
+
+	/* 使用Druid连接池时产生的属性 */
+	protected static String getConnectionPropertiesDruid(DataMapping dataMapping) throws Exception {
+		try {
+			String str = "filters=stat, poolPreparedStatements=true, maxActive=5, minIdle=0, testOnBorrow=true, Username="
+					+ dataMapping.getUsername() + ", Password=" + dataMapping.getPassword();
+			// String str = "filters=stat, poolPreparedStatements=true,
+			// maxActive=20, minIdle=0, timeBetweenEvictionRunsMillis=100000,
+			// minEvictableIdleTimeMillis=300000, Username="
+			// + dataMapping.getUsername() + ", Password=" +
+			// dataMapping.getPassword();
+			if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_db2)) {
+				str += ", validationQuery=" + validationQuery_db2 + ", driverClassName=" + driver_db2 + ", url="
+						+ dataMapping.getUrl();
+			}
+			if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_oracle)) {
+				str += ", validationQuery=" + validationQuery_oracle + ", driverClassName=" + driver_oracle + ", url="
+						+ dataMapping.getUrl();
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_mysql)) {
+				String url = dataMapping.getUrl();
+				// url += "?autoReconnect=true";
+				str += ", validationQuery=" + validationQuery_mysql + ", driverClassName=" + driver_mysql + ", url="
+						+ url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_postgresql)) {
+				String url = dataMapping.getUrl();
+				str += ", validationQuery=" + validationQuery_postgresql + ", driverClassName=" + driver_postgresql
+						+ ", url=" + url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_informix)) {
+				String url = dataMapping.getUrl();
+				str += ", validationQuery=" + validationQuery_informix + ", driverClassName=" + driver_informix
+						+ ", url=" + url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_h2)) {
+				String url = dataMapping.getUrl();
+				str += ", validationQuery=" + validationQuery_h2 + ", driverClassName=" + driver_h2 + ", url=" + url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_dm)) {
+				String url = dataMapping.getUrl();
+				str += ", validationQuery=" + validationQuery_dm + ", driverClassName=" + driver_dm + ", url=" + url;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_sqlserver)) {
+				String url = dataMapping.getUrl();
+				str += ", validationQuery=" + validationQuery_sqlserver + ", driverClassName=" + driver_sqlserver
+						+ ", url=" + url;
+			}
+			return str;
+		} catch (Exception e) {
+			throw new Exception("can not create connection properites", e);
+		}
+	}
+
+	/* 获取驱动名称 */
+	public static String getConnectionDriverName(DataMapping dataMapping) throws Exception {
+		try {
+			if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_db2)) {
+				return driver_db2;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_oracle)) {
+				return driver_oracle;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_mysql)) {
+				return driver_mysql;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_postgresql)) {
+				return driver_postgresql;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_informix)) {
+				return driver_informix;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_h2)) {
+				return driver_h2;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_dm)) {
+				return driver_dm;
+			} else if (StringUtils.equals(determineDBDictionary(dataMapping), dictionary_sqlserver)) {
+				return driver_sqlserver;
+			}
+			throw new Exception("database jdbc driver miss match:" + dataMapping.getUrl());
+		} catch (Exception e) {
+			throw new Exception("can not get driverClassName property", e);
+		}
+	}
+
+	/** 获取日志属性 */
+	protected static String getLog(DataMapping dataMapping) throws Exception {
+		try {
+			return "Tool=" + dataMapping.getToolLevel() + ", Enhance=" + dataMapping.getEnhanceLevel() + ", METADATA="
+					+ dataMapping.getMetaDataLevel() + ", RUNTIME=" + dataMapping.getRuntimeLevel() + ", Query="
+					+ dataMapping.getQueryLevel() + ", DataCache=" + dataMapping.getDataCacheLevel() + ", JDBC="
+					+ dataMapping.getJdbcLevel() + ", SQL=" + dataMapping.getSqlLevel();
+		} catch (Exception e) {
+			throw new Exception("can not get log property.", e);
+		}
+	}
+
+	public static String determineDBDictionary(DataMapping dataMapping) throws Exception {
+		try {
+			if (StringUtils.containsIgnoreCase(dataMapping.getUrl(), "jdbc:db2:")) {
+				return dictionary_db2;
+			} else if (StringUtils.containsIgnoreCase(dataMapping.getUrl(), "jdbc:oracle:")) {
+				return dictionary_oracle;
+			} else if (StringUtils.containsIgnoreCase(dataMapping.getUrl(), "jdbc:mysql:")) {
+				return dictionary_mysql;
+			} else if (StringUtils.containsIgnoreCase(dataMapping.getUrl(), "jdbc:postgresql:")) {
+				return dictionary_postgresql;
+			} else if (StringUtils.containsIgnoreCase(dataMapping.getUrl(), "jdbc:informix-sqli:")) {
+				return dictionary_informix;
+			} else if (StringUtils.containsIgnoreCase(dataMapping.getUrl(), "jdbc:h2:tcp:")) {
+				return dictionary_h2;
+			} else if (StringUtils.containsIgnoreCase(dataMapping.getUrl(), "jdbc:dm:")) {
+				return dictionary_dm;
+			} else if (StringUtils.containsIgnoreCase(dataMapping.getUrl(), "jdbc:sqlserver:")) {
+				return dictionary_sqlserver;
+			}
+			throw new Exception("database jdbc driver miss match:" + dataMapping.getUrl());
+		} catch (Exception e) {
+			throw new Exception("can not get driverClassName property", e);
+		}
+	}
+}

+ 25 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/AbstractPersistenceProperties.java

@@ -0,0 +1,25 @@
+package com.x.base.core.entity;
+
+public class AbstractPersistenceProperties {
+
+	public static final String defaultUnit = "x";
+
+	public static final String schema = "X";
+
+	public static final String orderColumn = "xorderColumn";
+
+	//public static final String xmlStrategy = "com.x.core.entity.xml.strats.XStreamValueHandler";
+
+	public static final int file_name_length = JpaObject.length_255B;
+
+	public static final int organization_name_length = JpaObject.length_255B;
+
+	public static final int processPlatform_name_length = JpaObject.length_255B;
+
+	public static final int processPlatform_title_length = JpaObject.length_255B;
+
+	public static final int component_name_length = JpaObject.length_255B;
+
+	public static final int length_sequence = JpaObject.length_128B;
+
+}

+ 343 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/JpaObject.java

@@ -0,0 +1,343 @@
+package com.x.base.core.entity;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Lob;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.openjpa.persistence.jdbc.ContainerTable;
+
+import com.x.base.core.entity.annotation.Flag;
+import com.x.base.core.entity.annotation.RestrictFlag;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.DateTools;
+import com.x.base.core.project.tools.ListTools;
+
+@MappedSuperclass
+public abstract class JpaObject extends GsonPropertyObject implements Serializable {
+
+	private static final long serialVersionUID = 2809501197843500002L;
+
+	public static String createId() {
+		return UUID.randomUUID().toString();
+	}
+
+	abstract public void onPersist() throws Exception;
+
+	public static final String ColumnNamePrefix = "x";
+
+	public static final String IndexNameMiddle = "_";
+
+	public static final String JoinIndexNameSuffix = "_join";
+
+	public static final String ElementIndexNameSuffix = "_element";
+
+	public static final String ContainerTableNameMiddle = "_";
+
+	public static final String DefaultUniqueConstraintSuffix = "DUC";
+
+	abstract public String getId();
+
+	abstract public void setId(String id);
+
+	// abstract public Date getCreateTime();
+	//
+	// abstract public void setCreateTime(Date createTime);
+	//
+	// abstract public Date getUpdateTime();
+	//
+	// abstract public void setUpdateTime(Date updateTime);
+	//
+	// abstract public String getSequence();
+	//
+	// abstract public void setSequence(String sequence);
+
+	public static final String id_FIELDNAME = "id";
+
+	public static final String createTime_FIELDNAME = "createTime";
+
+	public static final String updateTime_FIELDNAME = "updateTime";
+
+	public static final String sequence_FIELDNAME = "sequence";
+
+	public static final String distributeFactor_FIELDNAME = "distributeFactor";
+
+	public static final String password_FIELDNAME = "password";
+
+	public static final String scratchString_FIELDNAME = "scratchString";
+
+	public static final String scratchBoolean_FIELDNAME = "scratchBoolean";
+
+	public static final String scratchDate_FIELDNAME = "scratchDate";
+
+	public static final String scratchInteger_FIELDNAME = "scratchInteger";
+
+	public static final List<String> FieldsUnmodify = ListUtils.unmodifiableList(Arrays.asList(id_FIELDNAME,
+			distributeFactor_FIELDNAME, createTime_FIELDNAME, updateTime_FIELDNAME, sequence_FIELDNAME,
+			scratchString_FIELDNAME, scratchBoolean_FIELDNAME, scratchDate_FIELDNAME, scratchInteger_FIELDNAME));
+
+	public static final List<String> FieldsUnmodifyExcludeId = ListUtils.unmodifiableList(Arrays.asList(
+			distributeFactor_FIELDNAME, createTime_FIELDNAME, updateTime_FIELDNAME, sequence_FIELDNAME,
+			scratchString_FIELDNAME, scratchBoolean_FIELDNAME, scratchDate_FIELDNAME, scratchInteger_FIELDNAME));
+
+	public static final List<String> FieldsInvisible = ListUtils.unmodifiableList(
+			Arrays.asList(distributeFactor_FIELDNAME, sequence_FIELDNAME, password_FIELDNAME, scratchString_FIELDNAME,
+					scratchBoolean_FIELDNAME, scratchDate_FIELDNAME, scratchInteger_FIELDNAME));
+
+	@FieldDescribe("创建时间,自动生成,索引创建在约束中.")
+	@Column(name = ColumnNamePrefix + createTime_FIELDNAME)
+	private Date createTime;
+
+	@FieldDescribe("修改时间,自动生成,索引创建在约束中.")
+	@Column(name = ColumnNamePrefix + updateTime_FIELDNAME)
+	private Date updateTime;
+
+	@FieldDescribe("列表序号,由创建时间以及ID组成.在保存时自动生成,索引创建在约束中.")
+	@Column(length = JpaObject.length_128B, name = ColumnNamePrefix + sequence_FIELDNAME)
+	private String sequence;
+
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public Date getUpdateTime() {
+		return updateTime;
+	}
+
+	public void setUpdateTime(Date updateTime) {
+		this.updateTime = updateTime;
+	}
+
+	public String getSequence() {
+		return sequence;
+	}
+
+	public void setSequence(String sequence) {
+		this.sequence = sequence;
+	}
+
+	/* 暂存String */
+	@Column(length = length_255B, name = ColumnNamePrefix + scratchString_FIELDNAME)
+	private String scratchString;
+
+	/* 暂存Boolean */
+	@Column(name = ColumnNamePrefix + scratchBoolean_FIELDNAME)
+	private Boolean scratchBoolean;
+
+	/* 暂存Date */
+	@Column(name = ColumnNamePrefix + scratchDate_FIELDNAME)
+	private Date scratchDate;
+
+	/* 暂存Integer */
+	@Column(name = ColumnNamePrefix + scratchInteger_FIELDNAME)
+	private Date scratchInteger;
+
+	public String getScratchString() {
+		return scratchString;
+	}
+
+	public void setScratchString(String scratchString) {
+		this.scratchString = scratchString;
+	}
+
+	public Boolean getScratchBoolean() {
+		return scratchBoolean;
+	}
+
+	public void setScratchBoolean(Boolean scratchBoolean) {
+		this.scratchBoolean = scratchBoolean;
+	}
+
+	public Date getScratchDate() {
+		return scratchDate;
+	}
+
+	public void setScratchDate(Date scratchDate) {
+		this.scratchDate = scratchDate;
+	}
+
+	public Date getScratchInteger() {
+		return scratchInteger;
+	}
+
+	public void setScratchInteger(Date scratchInteger) {
+		this.scratchInteger = scratchInteger;
+	}
+
+	public static final int length_1B = 1;
+
+	public static final int length_2B = 2;
+
+	public static final int length_4B = 4;
+
+	public static final int length_8B = 8;
+
+	public static final int length_16B = 16;
+
+	public static final int length_32B = 32;
+
+	public static final int length_64B = 64;
+
+	public static final int length_96B = 96;
+
+	public static final int length_128B = 128;
+
+	public static final int length_255B = 255;
+
+	public static final int length_1K = 1024;
+
+	public static final int length_2K = 1024 * 2;
+
+	public static final int length_4K = 1024 * 4;
+
+	public static final int length_8K = 1024 * 8;
+
+	public static final int length_16K = 1024 * 16;
+
+	public static final int length_32K = 1024 * 32;
+
+	public static final int length_64K = 1024 * 64;
+
+	public static final int length_128K = 1024 * 128;
+
+	public static final int length_1M = 1048576;
+
+	public static final int length_10M = 1048576 * 10;
+
+	public static final int length_20M = 1048576 * 20;
+
+	public static final int length_50M = 1048576 * 50;
+
+	public static final int length_100M = length_10M * 10;
+
+	public static final int length_1G = 1073741824;
+
+	public static final int length_id = length_64B;
+
+	public static final String IDCOLUMN = "xid";
+	public static final String CREATETIMECOLUMN = "xcreateTime";
+	public static final String UPDATETIMECOLUMN = "xupdateTime";
+	public static final String SEQUENCECOLUMN = "xsequence";
+
+	public static final String DISTINGUISHEDNAME = "distinguishedName";
+
+	public static final String[] ID_DISTRIBUTEFACTOR = new String[] { id_FIELDNAME, distributeFactor_FIELDNAME };
+
+	public List<String> flagValues() throws Exception {
+		List<String> values = new ArrayList<>();
+		values.add(this.getId());
+		for (Field f : FieldUtils.getFieldsListWithAnnotation(this.getClass(), Flag.class)) {
+			values.add(PropertyUtils.getProperty(this, f.getName()).toString());
+		}
+		return ListTools.trim(values, true, true);
+	}
+
+	public List<String> restrictFlagValues() throws Exception {
+		List<String> values = this.flagValues();
+		for (Field f : FieldUtils.getFieldsListWithAnnotation(this.getClass(), RestrictFlag.class)) {
+			values.add(PropertyUtils.getProperty(this, f.getName()).toString());
+		}
+		return ListTools.trim(values, true, true);
+	}
+
+	public Object get(String name) throws Exception {
+		return PropertyUtils.getProperty(this, name);
+	}
+
+	@SuppressWarnings("unchecked")
+	public <T> T get(String name, Class<T> clazz) throws Exception {
+		Object o = get(name);
+		if (null == o) {
+			return null;
+		}
+		return (T) o;
+	}
+
+	public int hashCode() {
+		return 31 + ((this.getId() == null) ? 0 : this.getId().hashCode());
+	}
+
+	public boolean equals(Object o) {
+		if (null == o) {
+			return false;
+		}
+		if (!(o instanceof JpaObject)) {
+			return false;
+		} else {
+			return this.getId().equalsIgnoreCase(((JpaObject) o).getId());
+		}
+	}
+
+	public static <T extends JpaObject> List<String> singularAttributeField(Class<T> clz, Boolean excludeInvisible,
+			Boolean excludeLob) {
+		List<String> names = new ArrayList<>();
+		for (Field field : FieldUtils.getFieldsListWithAnnotation(clz, Column.class)) {
+			if (null == field.getAnnotation(ContainerTable.class)) {
+				if (BooleanUtils.isTrue(excludeInvisible) && FieldsInvisible.contains(field.getName())) {
+					continue;
+				}
+				if (BooleanUtils.isTrue(excludeLob) && (null != field.getAnnotation(Lob.class))) {
+					continue;
+				}
+				names.add(field.getName());
+			}
+		}
+		return names;
+	}
+
+	public String nameOfEntity() {
+		String name = this.getClass().getSimpleName();
+		return name;
+	}
+
+	@PrePersist
+	public void prePersist() throws Exception {
+		if (StringUtils.isEmpty(this.getId())) {
+			throw new Exception("basePrePersist error, id is empty, entity class:" + this.getClass().getName()
+					+ ", entity content:" + XGsonBuilder.toJson(this) + ".");
+		}
+		Date date = new Date();
+		if (null == this.getCreateTime()) {
+			this.setCreateTime(date);
+		}
+		this.setUpdateTime(date);
+		if (StringUtils.isEmpty(this.getSequence())) {
+			this.setSequence(StringUtils.join(DateTools.compact(this.getCreateTime()), this.getId()));
+		}
+		this.onPersist();
+	}
+
+	@PreUpdate
+	public void preUpdate() throws Exception {
+		if (StringUtils.isEmpty(this.getId())) {
+			throw new Exception("basePreUpdate error, id is empty, entity class:" + this.getClass().getName()
+					+ ", entity content:" + XGsonBuilder.toJson(this) + ".");
+		}
+		this.setUpdateTime(new Date());
+		if (StringUtils.isEmpty(this.getSequence())) {
+			this.setSequence(StringUtils.join(DateTools.compact(this.getCreateTime()), this.getId()));
+		}
+		this.onPersist();
+	}
+
+}

+ 24 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/JpaObject_.java

@@ -0,0 +1,24 @@
+/** 
+ *  Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package com.x.base.core.entity;
+
+import java.lang.Boolean;
+import java.lang.String;
+import java.util.Date;
+import javax.persistence.metamodel.SingularAttribute;
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=com.x.base.core.entity.JpaObject.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Fri Dec 14 16:02:59 CST 2018")
+public class JpaObject_ {
+    public static volatile SingularAttribute<JpaObject,Date> createTime;
+    public static volatile SingularAttribute<JpaObject,Boolean> scratchBoolean;
+    public static volatile SingularAttribute<JpaObject,Date> scratchDate;
+    public static volatile SingularAttribute<JpaObject,Date> scratchInteger;
+    public static volatile SingularAttribute<JpaObject,String> scratchString;
+    public static volatile SingularAttribute<JpaObject,String> sequence;
+    public static volatile SingularAttribute<JpaObject,Date> updateTime;
+}

+ 31 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/SliceJpaObject.java

@@ -0,0 +1,31 @@
+package com.x.base.core.entity;
+
+import javax.persistence.Column;
+import javax.persistence.MappedSuperclass;
+
+import com.x.base.core.project.annotation.FieldDescribe;
+
+@MappedSuperclass
+public abstract class SliceJpaObject extends JpaObject {
+
+	private static final long serialVersionUID = 805690971791595604L;
+
+	@FieldDescribe("分布式存储标识位.")
+	@Column(name = ColumnNamePrefix + distributeFactor_FIELDNAME)
+	protected Integer distributeFactor;
+
+	public Integer getDistributeFactor() {
+		return distributeFactor;
+	}
+
+	public void setDistributeFactor(Integer distributeFactor) {
+		this.distributeFactor = distributeFactor;
+	}
+
+	// protected void concreteDistributeFactor() {
+	// if (null == this.distributeFactor) {
+	// this.distributeFactor = (new Random()).nextInt(1000);
+	// }
+	// }
+
+}

+ 16 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/SliceJpaObject_.java

@@ -0,0 +1,16 @@
+/** 
+ *  Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package com.x.base.core.entity;
+
+import java.lang.Integer;
+import javax.persistence.metamodel.SingularAttribute;
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=com.x.base.core.entity.SliceJpaObject.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Fri Dec 14 16:02:59 CST 2018")
+public class SliceJpaObject_ extends JpaObject_  {
+    public static volatile SingularAttribute<SliceJpaObject,Integer> distributeFactor;
+}

+ 14 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/Storage.java

@@ -0,0 +1,14 @@
+package com.x.base.core.entity;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = ElementType.TYPE)
+@Inherited
+public @interface Storage {
+	StorageType type();
+}

+ 301 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageObject.java

@@ -0,0 +1,301 @@
+package com.x.base.core.entity;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.util.Date;
+
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.vfs2.CacheStrategy;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.cache.NullFilesCache;
+import org.apache.commons.vfs2.impl.StandardFileSystemManager;
+import org.apache.commons.vfs2.provider.ftp.FtpFileSystemConfigBuilder;
+import org.apache.commons.vfs2.provider.ftp.FtpFileType;
+
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.config.StorageMapping;
+import com.x.base.core.project.tools.DefaultCharset;
+
+@MappedSuperclass
+public abstract class StorageObject extends SliceJpaObject {
+
+	private static FileSystemManager FILESYSTEMANAGERINSTANCE;
+
+	private FileSystemManager getFileSystemManager() throws Exception {
+		if (FILESYSTEMANAGERINSTANCE == null) {
+			synchronized (StorageObject.class) {
+				if (FILESYSTEMANAGERINSTANCE == null) {
+					StandardFileSystemManager fs = new StandardFileSystemManager();
+					// DefaultFileSystemManager fs = new
+					// DefaultFileSystemManager();
+					// File file = new File(Config.base(), "local/temp/vfs");
+					// FileUtils.forceMkdir(file);
+					// fs.setTemporaryFileStore(new
+					// DefaultFileReplicator(file));
+					fs.setFilesCache(new NullFilesCache());
+					fs.setCacheStrategy(CacheStrategy.ON_RESOLVE);
+					fs.init();
+					FILESYSTEMANAGERINSTANCE = fs;
+				}
+			}
+		}
+		return FILESYSTEMANAGERINSTANCE;
+	}
+
+	private static final long serialVersionUID = 7823729771901802653L;
+
+	public static final String PATHSEPARATOR = "/";
+
+	abstract public String path() throws Exception;
+
+	abstract public String getStorage();
+
+	abstract public void setStorage(String storage);
+
+	abstract public Long getLength();
+
+	abstract public void setLength(Long length);
+
+	abstract public String getName();
+
+	abstract public void setName(String name);
+
+	abstract public String getExtension();
+
+	abstract public void setExtension(String extension);
+
+	abstract public Date getLastUpdateTime();
+
+	abstract public void setLastUpdateTime(Date lastUpdateTime);
+
+	@Transient
+	private byte[] bytes;
+
+	public byte[] getBytes() {
+		return bytes;
+	}
+
+	public void setBytes(byte[] bytes) {
+		this.bytes = bytes;
+	}
+
+	/** 将内容导入到bytes字段,用于进行导入导出 */
+	public Long dumpContent(StorageMapping mapping) throws Exception {
+		long length = -1L;
+		try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+			length = this.readContent(mapping, output);
+			if (length < 0) {
+				this.setBytes(new byte[] {});
+			} else {
+				this.setBytes(output.toByteArray());
+			}
+		}
+		return length;
+	}
+
+	/** 将导入的字节进行保存 */
+	public Long saveContent(StorageMapping mapping, byte[] bytes, String name) throws Exception {
+		try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
+			return saveContent(mapping, bais, name);
+		}
+	}
+
+	/** 将导入的流进行保存 */
+	public Long saveContent(StorageMapping mapping, InputStream input, String name) throws Exception {
+		this.setName(name);
+		this.setExtension(StringUtils.lowerCase(FilenameUtils.getExtension(name)));
+		return this.updateContent(mapping, input);
+	}
+
+	/** 更新Content内容 */
+	public Long updateContent(StorageMapping mapping, byte[] bytes) throws Exception {
+		try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
+			return updateContent(mapping, bais);
+		}
+	}
+
+	/** 更新Content内容 */
+	public Long updateContent(StorageMapping mapping, byte[] bytes, String name) throws Exception {
+		try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
+			if (StringUtils.isNotEmpty(name)) {
+				this.setName(name);
+				this.setExtension(StringUtils.lowerCase(FilenameUtils.getExtension(name)));
+			}
+			return updateContent(mapping, bais);
+		}
+	}
+
+	/** 更新Content内容 */
+	public Long updateContent(StorageMapping mapping, InputStream input, String name) throws Exception {
+		if (StringUtils.isNotEmpty(name)) {
+			this.setName(name);
+			this.setExtension(StringUtils.lowerCase(FilenameUtils.getExtension(name)));
+		}
+		return updateContent(mapping, input);
+	}
+
+	/** 更新Content内容 */
+	public Long updateContent(StorageMapping mapping, InputStream input) throws Exception {
+		long length = -1L;
+		FileSystemManager manager = this.getFileSystemManager();
+		String prefix = this.getPrefix(mapping);
+		String path = this.path();
+		if (StringUtils.isEmpty(path)) {
+			throw new Exception("path can not be empty.");
+		}
+		FileSystemOptions options = this.getOptions(mapping);
+		try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+			/* 由于可以在传输过程中取消传输,先拷贝到内存 */
+			IOUtils.copyLarge(input, baos);
+			try (FileObject fo = manager.resolveFile(prefix + PATHSEPARATOR + path, options);
+					OutputStream output = fo.getContent().getOutputStream()) {
+				length = IOUtils.copyLarge(new ByteArrayInputStream(baos.toByteArray()), output);
+				this.setLength(length);
+				manager.closeFileSystem(fo.getFileSystem());
+			}
+		}
+		this.setStorage(mapping.getName());
+		this.setLastUpdateTime(new Date());
+		return length;
+	}
+
+	/** 读出内容 */
+	public byte[] readContent(StorageMapping mapping) throws Exception {
+		try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+			readContent(mapping, baos);
+			return baos.toByteArray();
+		}
+	}
+
+	/** 将内容流出到output */
+	public Long readContent(StorageMapping mapping, OutputStream output) throws Exception {
+		long length = -1L;
+		FileSystemManager manager = this.getFileSystemManager();
+		String prefix = this.getPrefix(mapping);
+		String path = this.path();
+		FileSystemOptions options = this.getOptions(mapping);
+		try (FileObject fo = manager.resolveFile(prefix + PATHSEPARATOR + path, options)) {
+			if (fo.exists() && fo.isFile()) {
+				try (InputStream input = fo.getContent().getInputStream()) {
+					length = IOUtils.copyLarge(input, output);
+				}
+			}
+			manager.closeFileSystem(fo.getFileSystem());
+		}
+		return length;
+	}
+
+	/** 检查是否存在内容 */
+	public boolean existContent(StorageMapping mapping) throws Exception {
+		FileSystemManager manager = this.getFileSystemManager();
+		String prefix = this.getPrefix(mapping);
+		String path = this.path();
+		FileSystemOptions options = this.getOptions(mapping);
+		try (FileObject fo = manager.resolveFile(prefix + PATHSEPARATOR + path, options)) {
+			if (fo.exists() && fo.isFile()) {
+				return true;
+			}
+			return false;
+		}
+	}
+
+	/** 删除内容,同时判断上一级目录(只判断一级)是否为空,为空则删除上一级目录 */
+	public void deleteContent(StorageMapping mapping) throws Exception {
+		FileSystemManager manager = this.getFileSystemManager();
+		String prefix = this.getPrefix(mapping);
+		String path = this.path();
+		FileSystemOptions options = this.getOptions(mapping);
+		try (FileObject fo = manager.resolveFile(prefix + PATHSEPARATOR + path, options)) {
+			if (fo.exists() && fo.isFile()) {
+				fo.delete();
+				if ((!StringUtils.startsWith(path, PATHSEPARATOR)) && (StringUtils.contains(path, PATHSEPARATOR))) {
+					FileObject parent = fo.getParent();
+					if ((null != parent) && parent.exists() && parent.isFolder()) {
+						if (parent.getChildren().length == 0) {
+							parent.delete();
+						}
+					}
+				}
+			}
+			manager.closeFileSystem(fo.getFileSystem());
+		}
+	}
+
+	/* 取得完整访问路径的前半部分 */
+	private String getPrefix(StorageMapping mapping) throws Exception {
+		String prefix = "";
+		if (null == mapping.getProtocol()) {
+			throw new Exception("storage protocol is null.");
+		}
+		switch (mapping.getProtocol()) {
+		// bzip2,file, ftp, ftps, gzip, hdfs, http, https, jar, ram, res, sftp,
+		// tar, temp, webdav, zip, cifs, mime;
+		case ftp:
+			// ftp://[ username[: password]@] hostname[: port][ relative-path]
+			prefix = "ftp://" + mapping.getUsername() + ":"
+					+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
+					+ mapping.getPort();
+			break;
+		case cifs:
+			// smb://[ username[: password]@] hostname[: port][ absolute-path]
+			prefix = "smb://" + mapping.getUsername() + ":"
+					+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
+					+ mapping.getPort();
+			break;
+		default:
+			break;
+		}
+		return prefix;
+	}
+
+	private FileSystemOptions getOptions(StorageMapping mapping) throws Exception {
+		FileSystemOptions opts = new FileSystemOptions();
+		if (null == mapping.getProtocol()) {
+			throw new Exception("storage protocol is null.");
+		}
+		switch (mapping.getProtocol()) {
+		// bzip2,file, ftp, ftps, gzip, hdfs, http, https, jar, ram, res, sftp,
+		// tar, temp, webdav, zip, cifs, mime;
+		case ftp:
+			FtpFileSystemConfigBuilder builder = FtpFileSystemConfigBuilder.getInstance();
+			/*
+			 * 如果使用被动模式在阿里云centos7下会经常性出现无法连接 Caused by: java.net.ConnectException:
+			 * Connection timed out (Connection timed out) at
+			 * java.net.PlainSocketImpl.socketConnect(Native Method) at
+			 * java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
+			 * at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.
+			 * java:206) at
+			 * java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at
+			 * java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at
+			 * java.net.Socket.connect(Socket.java:589)
+			 */
+			builder.setPassiveMode(opts, Config.vfs().getFtp().getPassive());
+			// builder.setPassiveMode(opts, false);
+			// builder.setPassiveMode(opts, true);
+			/** 强制不校验IP */
+			builder.setRemoteVerification(opts, false);
+			// FtpFileType.BINARY is the default
+			builder.setFileType(opts, FtpFileType.BINARY);
+			builder.setConnectTimeout(opts, 10000);
+			builder.setSoTimeout(opts, 10000);
+			builder.setControlEncoding(opts, DefaultCharset.name);
+			break;
+		case cifs:
+			break;
+		default:
+			break;
+		}
+		return opts;
+	}
+
+}

+ 13 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageObject_.java

@@ -0,0 +1,13 @@
+/** 
+ *  Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package com.x.base.core.entity;
+
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=com.x.base.core.entity.StorageObject.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Fri Dec 14 16:02:59 CST 2018")
+public class StorageObject_ extends SliceJpaObject_  {
+}

+ 6 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageProtocol.java

@@ -0,0 +1,6 @@
+package com.x.base.core.entity;
+
+public enum StorageProtocol {
+	bzip2, file, ftp, ftps, gzip, hdfs, http, https, jar, ram, res, sftp, tar, temp, webdav, zip, cifs, mime;
+	public static final int length = JpaObject.length_16B;
+}

+ 6 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageType.java

@@ -0,0 +1,6 @@
+package com.x.base.core.entity;
+
+public enum StorageType {
+	file, processPlatform, meeting, calendar, okr, cms, bbs, report, strategyDeploy;
+	public static final int length = JpaObject.length_32B;
+}

+ 38 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CheckPersist.java

@@ -0,0 +1,38 @@
+package com.x.base.core.entity.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@Inherited
+public @interface CheckPersist {
+
+	boolean allowEmpty() default true;
+
+	boolean allowContainEmpty() default true;
+
+	boolean simplyString() default false;
+
+	boolean fileNameString() default false;
+
+	boolean mailString() default false;
+
+	boolean mobileString() default false;
+
+	CitationExist[] citationExists() default {};
+
+	CitationNotExist[] citationNotExists() default {};
+
+	String pattern() default "";
+
+	String min() default "";
+
+	String max() default "";
+
+	String[] excludes() default {};
+
+}

+ 5 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CheckPersistType.java

@@ -0,0 +1,5 @@
+package com.x.base.core.entity.annotation;
+
+public enum CheckPersistType {
+	baseOnly, citationOnly, all, none
+}

+ 20 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CheckRemove.java

@@ -0,0 +1,20 @@
+package com.x.base.core.entity.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@Inherited
+public @interface CheckRemove {
+
+	CitationExist[] citationExists() default {};
+
+	CitationNotExist[] citationNotExists() default {};
+
+	String[] excludes() default {};
+
+}

+ 5 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CheckRemoveType.java

@@ -0,0 +1,5 @@
+package com.x.base.core.entity.annotation;
+
+public enum CheckRemoveType {
+	all, none
+}

+ 24 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CitationExist.java

@@ -0,0 +1,24 @@
+package com.x.base.core.entity.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.x.base.core.entity.JpaObject;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface CitationExist {
+
+	Class<? extends JpaObject> type();
+
+	String[] fields() default {"id"};
+
+	Equal[] equals() default {};
+
+	NotEqual[] notEquals() default {};
+
+	String[] excludes() default {};
+	
+}

+ 22 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/CitationNotExist.java

@@ -0,0 +1,22 @@
+package com.x.base.core.entity.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.x.base.core.entity.JpaObject;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface CitationNotExist {
+
+	Class<? extends JpaObject> type();
+
+	String[] fields() default { "id" };
+
+	Equal[] equals() default {};
+
+	NotEqual[] notEquals() default {};
+
+}

+ 18 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/ContainerEntity.java

@@ -0,0 +1,18 @@
+package com.x.base.core.entity.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 用于标识Entity,由于@Entity标识可能扫描到其他的类,所以这里单独用一个标识,表示是自建的类,这样可以在scan 的时候区分
+ * 
+ * @author zhour
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ContainerEntity {
+
+}

+ 9 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/Equal.java

@@ -0,0 +1,9 @@
+package com.x.base.core.entity.annotation;
+
+public @interface Equal {
+
+	String property();
+
+	String field();
+
+}

+ 14 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/Flag.java

@@ -0,0 +1,14 @@
+package com.x.base.core.entity.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@Inherited
+public @interface Flag {
+
+}

+ 16 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/IdReference.java

@@ -0,0 +1,16 @@
+package com.x.base.core.entity.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.x.base.core.entity.JpaObject;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@Inherited
+public @interface IdReference {
+	Class<? extends JpaObject>[] value();
+}

+ 9 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/NotEqual.java

@@ -0,0 +1,9 @@
+package com.x.base.core.entity.annotation;
+
+public @interface NotEqual {
+
+	String property();
+
+	String field();
+
+}

+ 14 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/annotation/RestrictFlag.java

@@ -0,0 +1,14 @@
+package com.x.base.core.entity.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@Inherited
+public @interface RestrictFlag {
+	String[] fields() default {};
+}

+ 378 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/DataItem.java

@@ -0,0 +1,378 @@
+package com.x.base.core.entity.dataitem;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.SliceJpaObject;
+import com.x.base.core.project.tools.DateTools;
+import com.x.base.core.project.tools.StringTools;
+
+public abstract class DataItem extends SliceJpaObject {
+
+	private static final long serialVersionUID = -709083599148957321L;
+
+	public static final int pathLength = JpaObject.length_64B;
+
+	public static final int STRING_VALUE_MAX_LENGTH = JpaObject.length_255B;
+
+	public String getStringValue() {
+		if (StringUtils.isNotEmpty(this.getStringLongValue())) {
+			return this.getStringLongValue();
+		} else {
+			return this.getStringShortValue();
+		}
+	}
+
+	public void setStringValue(String stringValue) {
+		if (StringTools.utf8Length(stringValue) > STRING_VALUE_MAX_LENGTH) {
+			this.setStringShortValue(StringTools.utf8SubString(stringValue, STRING_VALUE_MAX_LENGTH));
+			this.setStringLongValue(stringValue);
+		} else {
+			this.setStringShortValue(stringValue);
+			this.setStringLongValue(null);
+		}
+	}
+
+	public abstract ItemType getItemType();
+
+	public abstract void setItemType(ItemType itemType);
+
+	public abstract ItemPrimitiveType getItemPrimitiveType();
+
+	public abstract void setItemPrimitiveType(ItemPrimitiveType itemPrimitiveType);
+
+	public abstract ItemStringValueType getItemStringValueType();
+
+	public abstract void setItemStringValueType(ItemStringValueType itemStringValueType);
+
+	public static final String path0_FIELDNAME = "path0";
+
+	public static final String path1_FIELDNAME = "path1";
+
+	public static final String path2_FIELDNAME = "path2";
+
+	public static final String path3_FIELDNAME = "path3";
+
+	public static final String path4_FIELDNAME = "path4";
+
+	public static final String path5_FIELDNAME = "path5";
+
+	public static final String path6_FIELDNAME = "path6";
+
+	public static final String path7_FIELDNAME = "path7";
+
+	public static final String path0Location_FIELDNAME = "path0Location";
+
+	public static final String path1Location_FIELDNAME = "path1Location";
+
+	public static final String path2Location_FIELDNAME = "path2Location";
+
+	public static final String path3Location_FIELDNAME = "path3Location";
+
+	public static final String path4Location_FIELDNAME = "path4Location";
+
+	public static final String path5Location_FIELDNAME = "path5Location";
+
+	public static final String path6Location_FIELDNAME = "path6Location";
+
+	public static final String path7Location_FIELDNAME = "path7Location";
+
+	public static final String itemCategory_FIELDNAME = "itemCategory";
+
+	public static final String itemType_FIELDNAME = "itemType";
+
+	public static final String itemPrimitiveType_FIELDNAME = "itemPrimitiveType";
+
+	public static final String itemStringValueType_FIELDNAME = "itemStringValueType";
+
+	public static final String bundle_FIELDNAME = "bundle";
+
+	public static final String stringShortValue_FIELDNAME = "stringShortValue";
+
+	public static final String stringLongValue_FIELDNAME = "stringLongValue";
+
+	public static final String numberValue_FIELDNAME = "numberValue";
+
+	public static final String dateTimeValue_FIELDNAME = "dateTimeValue";
+
+	public static final String dateValue_FIELDNAME = "dateValue";
+
+	public static final String timeValue_FIELDNAME = "timeValue";
+
+	public static final String booleanValue_FIELDNAME = "booleanValue";
+
+	public static final String BUNDLECOLUMN = ColumnNamePrefix + bundle_FIELDNAME;
+	public static final String ITEMCATEGORYCOLUMN = ColumnNamePrefix + itemCategory_FIELDNAME;
+	public static final String PATH0COLUMN = ColumnNamePrefix + path0_FIELDNAME;
+	public static final String PATH1COLUMN = ColumnNamePrefix + path1_FIELDNAME;
+	public static final String PATH2COLUMN = ColumnNamePrefix + path2_FIELDNAME;
+	public static final String PATH3COLUMN = ColumnNamePrefix + path3_FIELDNAME;
+	public static final String PATH4COLUMN = ColumnNamePrefix + path4_FIELDNAME;
+	public static final String PATH5COLUMN = ColumnNamePrefix + path5_FIELDNAME;
+	public static final String PATH6COLUMN = ColumnNamePrefix + path6_FIELDNAME;
+	public static final String PATH7COLUMN = ColumnNamePrefix + path7_FIELDNAME;
+	public static final String ITEMTYPECOLUMN = ColumnNamePrefix + itemType_FIELDNAME;
+	public static final String ITEMPRIMITIVETYPECOLUMN = ColumnNamePrefix + itemPrimitiveType_FIELDNAME;
+	public static final String ITEMSTRINGVALUETYPECOLUMN = ColumnNamePrefix + itemStringValueType_FIELDNAME;
+
+	public abstract String getPath0();
+
+	public abstract void setPath0(String path0);
+
+	public abstract String getPath1();
+
+	public abstract void setPath1(String path1);
+
+	public abstract String getPath2();
+
+	public abstract void setPath2(String path2);
+
+	public abstract String getPath3();
+
+	public abstract void setPath3(String path3);
+
+	public abstract String getPath4();
+
+	public abstract void setPath4(String path4);
+
+	public abstract String getPath5();
+
+	public abstract void setPath5(String path5);
+
+	public abstract String getPath6();
+
+	public abstract void setPath6(String path6);
+
+	public abstract String getPath7();
+
+	public abstract void setPath7(String path7);
+
+	public abstract String getStringShortValue();
+
+	public abstract void setStringShortValue(String stringValue);
+
+	public abstract String getStringLongValue();
+
+	public abstract void setStringLongValue(String stringValue);
+
+	public abstract Double getNumberValue();
+
+	public abstract void setNumberValue(Double numberValue);
+
+	public abstract Date getDateTimeValue();
+
+	public abstract void setDateTimeValue(Date dateTimeValue);
+
+	public abstract Date getDateValue();
+
+	public abstract void setDateValue(Date dateValue);
+
+	public abstract Date getTimeValue();
+
+	public abstract void setTimeValue(Date timeValue);
+
+	public abstract Boolean getBooleanValue();
+
+	public abstract void setBooleanValue(Boolean booleanValue);
+
+	public abstract Integer getPath0Location();
+
+	public abstract void setPath0Location(Integer path0Location);
+
+	public abstract Integer getPath1Location();
+
+	public abstract void setPath1Location(Integer path1Location);
+
+	public abstract Integer getPath2Location();
+
+	public abstract void setPath2Location(Integer path2Location);
+
+	public abstract Integer getPath3Location();
+
+	public abstract void setPath3Location(Integer path3Location);
+
+	public abstract Integer getPath4Location();
+
+	public abstract void setPath4Location(Integer path4Location);
+
+	public abstract Integer getPath5Location();
+
+	public abstract void setPath5Location(Integer path5Location);
+
+	public abstract Integer getPath6Location();
+
+	public abstract void setPath6Location(Integer path6Location);
+
+	public abstract Integer getPath7Location();
+
+	public abstract void setPath7Location(Integer path7Location);
+
+	public abstract ItemCategory getItemCategory();
+
+	public abstract void setItemCategory(ItemCategory itemCategory);
+
+	public abstract String getBundle();
+
+	public abstract void setBundle(String bundle);
+
+	public void value(Boolean value) {
+		this.setItemPrimitiveType(ItemPrimitiveType.b);
+		this.setItemStringValueType(ItemStringValueType.u);
+		this.setBooleanValue(value);
+	}
+
+	public void value(Double value) {
+		this.setItemPrimitiveType(ItemPrimitiveType.n);
+		this.setItemStringValueType(ItemStringValueType.u);
+		this.setNumberValue(value);
+	}
+
+	public void value(String value) throws Exception {
+		this.setItemPrimitiveType(ItemPrimitiveType.s);
+		this.setStringValue(value);
+		this.setItemStringValueType(ItemStringValueType.s);
+		if (StringTools.utf8Length(value) < STRING_VALUE_MAX_LENGTH) {
+			Date dateTime = DateTools.parseDateTime(value);
+			if (null != dateTime) {
+				this.setItemStringValueType(ItemStringValueType.dt);
+				this.setDateTimeValue(dateTime);
+				return;
+			}
+			Date date = DateTools.parseDate(value);
+			if (null != date) {
+				this.setItemStringValueType(ItemStringValueType.d);
+				this.setDateValue(date);
+				return;
+			}
+			Date time = DateTools.parseTime(value);
+			if (null != time) {
+				this.setItemStringValueType(ItemStringValueType.t);
+				this.setTimeValue(time);
+				return;
+			}
+		}
+	}
+
+	public List<String> paths() {
+		List<String> list = new ArrayList<>();
+		if (StringUtils.isNotEmpty(this.getPath0())) {
+			list.add(this.getPath0());
+		}
+		if (StringUtils.isNotEmpty(this.getPath1())) {
+			list.add(this.getPath1());
+		}
+		if (StringUtils.isNotEmpty(this.getPath2())) {
+			list.add(this.getPath2());
+		}
+		if (StringUtils.isNotEmpty(this.getPath3())) {
+			list.add(this.getPath3());
+		}
+		if (StringUtils.isNotEmpty(this.getPath4())) {
+			list.add(this.getPath4());
+		}
+		if (StringUtils.isNotEmpty(this.getPath5())) {
+			list.add(this.getPath5());
+		}
+		if (StringUtils.isNotEmpty(this.getPath6())) {
+			list.add(this.getPath6());
+		}
+		if (StringUtils.isNotEmpty(this.getPath7())) {
+			list.add(this.getPath7());
+		}
+		return list;
+	}
+
+	public String path() {
+		return StringUtils.join(this.paths().toArray(), ".");
+	}
+
+	public void path(List<String> paths) {
+		int i = 0;
+		for (String str : paths) {
+			this.path(str, i++);
+		}
+		for (int p = i; p < 8; p++) {
+			this.path("", p);
+		}
+	}
+
+	public void path(String str, Integer p) {
+		switch (p) {
+		case 0:
+			this.setPath0(str);
+		case 1:
+			this.setPath1(str);
+		case 2:
+			this.setPath2(str);
+		case 3:
+			this.setPath3(str);
+		case 4:
+			this.setPath4(str);
+		case 5:
+			this.setPath5(str);
+		case 6:
+			this.setPath6(str);
+		case 7:
+			this.setPath7(str);
+		}
+	}
+
+	public String path(Integer p) {
+		switch (p) {
+		case 0:
+			return this.getPath0();
+		case 1:
+			return this.getPath1();
+		case 2:
+			return this.getPath2();
+		case 3:
+			return this.getPath3();
+		case 4:
+			return this.getPath4();
+		case 5:
+			return this.getPath5();
+		case 6:
+			return this.getPath6();
+		case 7:
+			return this.getPath7();
+		}
+		return null;
+	}
+
+	public Integer pathLocation(Integer p) {
+		switch (p) {
+		case 0:
+			return this.getPath0Location();
+		case 1:
+			return this.getPath1Location();
+		case 2:
+			return this.getPath2Location();
+		case 3:
+			return this.getPath3Location();
+		case 4:
+			return this.getPath4Location();
+		case 5:
+			return this.getPath5Location();
+		case 6:
+			return this.getPath6Location();
+		case 7:
+			return this.getPath7Location();
+		}
+		return null;
+	}
+
+	@Override
+	public String toString() {
+		return "Item [path0=" + getPath0() + ", path1=" + getPath1() + ", path2=" + getPath2() + ", path3=" + getPath3()
+				+ ", path4=" + getPath4() + ", path5=" + getPath5() + ", path6=" + getPath6() + ", path7=" + getPath7()
+				+ ", stringValue=" + getStringValue() + ", numberValue=" + getNumberValue() + ", dateTimeValue="
+				+ getDateTimeValue() + ", dateValue=" + getDateValue() + ", timeValue=" + getTimeValue()
+				+ ", booleanValue=" + getBooleanValue() + ", itemType=" + getItemType() + ", itemPrimitiveType="
+				+ getItemPrimitiveType() + ", itemStringValueType=" + getItemStringValueType() + "]";
+	}
+
+}

+ 350 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/DataItemConverter.java

@@ -0,0 +1,350 @@
+package com.x.base.core.entity.dataitem;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Objects;
+
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.organization.OrganizationDefinition;
+import com.x.base.core.project.tools.StringTools;
+
+public class DataItemConverter<T extends DataItem> {
+
+	public static final int STRING_VALUE_MAX_LENGTH = JpaObject.length_255B;
+
+	private Class<T> clz;
+
+	public DataItemConverter(Class<T> clz) {
+		this.clz = clz;
+	}
+
+	public List<T> disassemble(JsonElement root, String... prefixPaths) throws Exception {
+		List<String> paths = new ArrayList<>();
+		for (String str : prefixPaths) {
+			paths.add(str);
+		}
+		List<T> list = this.disassemble(root, paths, new ArrayList<T>());
+		/**
+		 * 20170905 通过 javascripting 转换的Map将 array -> {0:"xxxxx"}
+		 * 的格式,变成了一个对象而非array,所以这里需要进行单独的判断,把用数字下标的Map强制设置为List
+		 */
+		for (int i = 0; i < (list.size() - 1); i++) {
+			/** 因为要取下一个,循环不用取最后一个数. */
+			T t = list.get(i);
+			if (t.getItemType() == ItemType.o) {
+				T next = list.get(i + 1);
+				/** 是一个数字的值,说明是数组中的一个 */
+				if (NumberUtils.isNumber(next.paths().get(next.paths().size() - 1))) {
+					/** 说明上一个T应该是一个Array */
+					t.setItemType(ItemType.a);
+				}
+			}
+		}
+		return list;
+	}
+
+	private List<T> disassemble(JsonElement root, List<String> paths, List<T> list) throws Exception {
+		T t = clz.newInstance();
+		t.path(paths);
+		list.add(t);
+		if (root.isJsonPrimitive()) {
+			t.setItemType(ItemType.p);
+			JsonPrimitive jsonPrimitive = root.getAsJsonPrimitive();
+			if (jsonPrimitive.isBoolean()) {
+				t.setItemPrimitiveType(ItemPrimitiveType.b);
+				t.setItemStringValueType(ItemStringValueType.u);
+				t.value(jsonPrimitive.getAsBoolean());
+			} else if (jsonPrimitive.isNumber()) {
+				t.setItemPrimitiveType(ItemPrimitiveType.n);
+				t.setItemStringValueType(ItemStringValueType.u);
+				t.value(jsonPrimitive.getAsDouble());
+			} else if (jsonPrimitive.isString()) {
+				t.setItemPrimitiveType(ItemPrimitiveType.s);
+				t.setItemStringValueType(ItemStringValueType.s);
+				t.value(jsonPrimitive.getAsString());
+			}
+		} else if (root.isJsonArray()) {
+			t.setItemType(ItemType.a);
+			t.setItemPrimitiveType(ItemPrimitiveType.u);
+			t.setItemStringValueType(ItemStringValueType.u);
+			int i = 0;
+			for (JsonElement o : root.getAsJsonArray()) {
+				List<String> ps = new ArrayList<>(paths);
+				ps.add(Integer.toString(i++));
+				this.disassemble(o, ps, list);
+			}
+		} else if (root.isJsonNull()) {
+			t.setItemType(ItemType.n);
+			t.setItemPrimitiveType(ItemPrimitiveType.u);
+			t.setItemStringValueType(ItemStringValueType.u);
+		} else if (root.isJsonObject()) {
+			t.setItemType(ItemType.o);
+			t.setItemPrimitiveType(ItemPrimitiveType.u);
+			t.setItemStringValueType(ItemStringValueType.u);
+			for (Entry<String, JsonElement> entry : root.getAsJsonObject().entrySet()) {
+				List<String> ps = new ArrayList<String>(paths);
+				ps.add(entry.getKey());
+				this.disassemble(entry.getValue(), ps, list);
+			}
+		}
+		return list;
+	}
+
+	public JsonElement assemble(List<T> list) {
+		return this.assemble(list, null);
+	}
+
+	public JsonElement assemble(List<T> list, Integer retract) {
+		try {
+			JsonElement root = null;
+			List<T> sorted = new ArrayList<>(list);
+			this.sort(sorted);
+			for (T t : sorted) {
+				root = this.assemble(sorted, t, retract, root);
+			}
+			return root;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	private JsonElement assemble(List<T> list, T t, Integer retract, JsonElement root) throws Exception {
+		JsonElement jsonElement = null;
+		if (t.getItemType().equals(ItemType.p)) {
+			if (t.getItemPrimitiveType().equals(ItemPrimitiveType.s)) {
+				jsonElement = new JsonPrimitive(Objects.toString(t.getStringValue(), ""));
+			} else if (t.getItemPrimitiveType().equals(ItemPrimitiveType.n)) {
+				jsonElement = new JsonPrimitive(t.getNumberValue());
+			} else if (t.getItemPrimitiveType().equals(ItemPrimitiveType.b)) {
+				jsonElement = new JsonPrimitive(t.getBooleanValue());
+			}
+		} else if (t.getItemType().equals(ItemType.o)) {
+			jsonElement = new JsonObject();
+		} else if (t.getItemType().equals(ItemType.a)) {
+			jsonElement = new JsonArray();
+		} else if (t.getItemType().equals(ItemType.n)) {
+			jsonElement = JsonNull.INSTANCE;
+		}
+		if (root == null) {
+			return jsonElement;
+		}
+		List<String> paths = t.paths();
+		if (null != retract) {
+			paths = paths.subList(retract, paths.size());
+		}
+		String name = paths.get(paths.size() - 1);
+		JsonElement o = root;
+		for (int i = 0; i < paths.size() - 1; i++) {
+			String path = paths.get(i);
+			if (!NumberUtils.isNumber(path)) {
+				o = o.getAsJsonObject().get(path);
+			} else {
+				o = o.getAsJsonArray().get(Integer.parseInt(path));
+			}
+		}
+		if (!NumberUtils.isNumber(name)) {
+			o.getAsJsonObject().add(name, jsonElement);
+		} else {
+			o.getAsJsonArray().add(jsonElement);
+		}
+		return root;
+	}
+
+	public void sort(List<T> list) {
+		Collections.sort(list, new Comparator<T>() {
+			public int compare(T o1, T o2) {
+				int c = 0;
+				c = comparePathLocation(o1.getPath0Location(), o2.getPath0Location());
+				if (c == 0) {
+					c = comparePath(o1.getPath0(), o2.getPath0());
+					if (c == 0) {
+						c = comparePathLocation(o1.getPath1Location(), o2.getPath1Location());
+						if (c == 0) {
+							c = comparePath(o1.getPath1(), o2.getPath1());
+							if (c == 0) {
+								c = comparePathLocation(o1.getPath2Location(), o2.getPath2Location());
+								if (c == 0) {
+									c = comparePath(o1.getPath2(), o2.getPath2());
+									if (c == 0) {
+										c = comparePathLocation(o1.getPath3Location(), o2.getPath3Location());
+										if (c == 0) {
+											c = comparePath(o1.getPath3(), o2.getPath3());
+											if (c == 0) {
+												c = comparePathLocation(o1.getPath4Location(), o2.getPath4Location());
+												if (c == 0) {
+													c = comparePath(o1.getPath4(), o2.getPath4());
+													if (c == 0) {
+														c = comparePathLocation(o1.getPath5Location(),
+																o2.getPath5Location());
+														if (c == 0) {
+															c = comparePath(o1.getPath5(), o2.getPath5());
+															if (c == 0) {
+																c = comparePathLocation(o1.getPath6Location(),
+																		o2.getPath6Location());
+																if (c == 0) {
+																	c = comparePath(o1.getPath6(), o2.getPath6());
+																	if (c == 0) {
+																		c = comparePathLocation(o1.getPath7Location(),
+																				o2.getPath7Location());
+																		if (c == 0) {
+																			c = comparePath(o1.getPath7(),
+																					o2.getPath7());
+																		}
+																	}
+																}
+															}
+														}
+													}
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+				return c;
+			}
+		});
+	}
+
+	private int comparePath(String p1, String p2) {
+		if (StringUtils.isEmpty(p1) && StringUtils.isEmpty(p2)) {
+			return 0;
+		} else if (StringUtils.isEmpty(p1)) {
+			return -1;
+		} else if (StringUtils.isEmpty(p2)) {
+			return 1;
+		}
+		return ObjectUtils.compare(p1, p2);
+	}
+
+	private int comparePathLocation(Integer pl1, Integer pl2) {
+		if ((null == pl1) && (null == pl2)) {
+			return 0;
+		} else if (null == pl1) {
+			return -1;
+		} else if (null == pl2) {
+			return 1;
+		}
+		return ObjectUtils.compare(pl1, pl2);
+	}
+
+	public List<T> subtract(List<T> l1, List<T> l2) throws Exception {
+		List<T> result = new ArrayList<>();
+		List<T> list2 = new ArrayList<>(l2);
+		T dummy = null;
+		next: for (T t1 : l1) {
+			if (null != dummy) {
+				list2.remove(dummy);
+			}
+			for (T t2 : list2) {
+				if (this.equate(t1, t2)) {
+					dummy = t2;
+					continue next;
+				}
+			}
+			result.add(t1);
+		}
+		return result;
+	}
+
+	public boolean equate(T t1, T t2) {
+		if (!Objects.equals(t1.getPath0(), t2.getPath0())) {
+			return false;
+		}
+		if (!Objects.equals(t1.getPath1(), t2.getPath1())) {
+			return false;
+		}
+		if (!Objects.equals(t1.getPath2(), t2.getPath2())) {
+			return false;
+		}
+		if (!Objects.equals(t1.getPath3(), t2.getPath3())) {
+			return false;
+		}
+		if (!Objects.equals(t1.getPath4(), t2.getPath4())) {
+			return false;
+		}
+		if (!Objects.equals(t1.getPath5(), t2.getPath5())) {
+			return false;
+		}
+		if (!Objects.equals(t1.getPath6(), t2.getPath6())) {
+			return false;
+		}
+		if (!Objects.equals(t1.getPath7(), t2.getPath7())) {
+			return false;
+		}
+		if (!Objects.equals(t1.getItemType(), t2.getItemType())) {
+			return false;
+		} else if (Objects.equals(t1.getItemType(), ItemType.p)) {
+			if (!Objects.equals(t1.getItemPrimitiveType(), t2.getItemPrimitiveType())) {
+				return false;
+			} else {
+				if (t1.getItemPrimitiveType().equals(ItemPrimitiveType.s)) {
+					if (!Objects.equals(t1.getItemStringValueType(), t2.getItemStringValueType())) {
+						return false;
+					} else {
+						return Objects.equals(t1.getStringValue(), t2.getStringValue());
+					}
+				} else if (t1.getItemPrimitiveType().equals(ItemPrimitiveType.n)) {
+					return Objects.equals(t1.getNumberValue(), t2.getNumberValue());
+				} else if (t1.getItemPrimitiveType().equals(ItemPrimitiveType.b)) {
+					return Objects.equals(t1.getBooleanValue(), t2.getBooleanValue());
+				}
+			}
+		}
+		return true;
+	}
+
+	public String text(List<T> items, boolean escapeNumber, boolean escapeBoolean, boolean escapeId,
+			boolean simplifyDistinguishedName, boolean htmlToText, String split) {
+		StringBuffer buffer = new StringBuffer();
+		this.sort(items);
+		for (T t : items) {
+			if (Objects.equals(t.getItemType(), ItemType.p)) {
+				if (Objects.equals(t.getItemPrimitiveType(), ItemPrimitiveType.s)
+						&& StringUtils.isNotEmpty(t.getStringValue())) {
+					if (escapeId && StringTools.isUUIDFormat(t.getStringValue())) {
+						continue;
+					}
+					if (simplifyDistinguishedName && OrganizationDefinition.isDistinguishedName(t.getStringValue())) {
+						buffer.append(OrganizationDefinition.name(t.getStringValue()));
+						buffer.append(split);
+						continue;
+					}
+					if (htmlToText) {
+						buffer.append(t.getStringValue().replaceAll("(?s)<[^>]*>(\\s*<[^>]*>)*", ""));
+						buffer.append(split);
+						continue;
+					}
+					buffer.append(t.getStringValue());
+				}
+				if (Objects.equals(t.getItemPrimitiveType(), ItemPrimitiveType.b) && (null != t.getBooleanValue())
+						&& (!escapeBoolean)) {
+					buffer.append(Objects.toString(t.getBooleanValue()));
+					buffer.append(split);
+				}
+				if (Objects.equals(t.getItemPrimitiveType(), ItemPrimitiveType.n) && (null != t.getNumberValue())
+						&& (!escapeNumber)) {
+					buffer.append(Objects.toString(t.getNumberValue()));
+					buffer.append(split);
+				}
+			}
+		}
+		return buffer.toString();
+	}
+}

+ 8 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/ItemCategory.java

@@ -0,0 +1,8 @@
+package com.x.base.core.entity.dataitem;
+
+import com.x.base.core.entity.JpaObject;
+
+public enum ItemCategory {
+	pp, cms, bbs, pp_dict;
+	public static final int length = JpaObject.length_16B;
+}

+ 8 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/ItemPrimitiveType.java

@@ -0,0 +1,8 @@
+package com.x.base.core.entity.dataitem;
+
+import com.x.base.core.entity.JpaObject;
+
+public enum ItemPrimitiveType {
+	s, b, n, u;
+	public static final int length = JpaObject.length_1B;
+}

+ 8 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/ItemStringValueType.java

@@ -0,0 +1,8 @@
+package com.x.base.core.entity.dataitem;
+
+import com.x.base.core.entity.JpaObject;
+
+public enum ItemStringValueType {
+	s, d, t, dt, u;
+	public static final int length = JpaObject.length_2B;
+}

+ 8 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/dataitem/ItemType.java

@@ -0,0 +1,8 @@
+package com.x.base.core.entity.dataitem;
+
+import com.x.base.core.entity.JpaObject;
+
+public enum ItemType {
+	o, a, p, n;
+	public static final int length = JpaObject.length_1B;
+}

+ 109 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/EnhancePersistenceXmlWriter.java

@@ -0,0 +1,109 @@
+package com.x.base.core.entity.tools;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.Entity;
+import javax.persistence.MappedSuperclass;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.QName;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+
+import com.x.base.core.project.Packages;
+import com.x.base.core.project.tools.MainTools;
+
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
+
+public class EnhancePersistenceXmlWriter {
+	public static void main(String[] args) throws Exception {
+		Argument arg = MainTools.parseArgument(args[0], Argument.class);
+		write(arg);
+	}
+
+	private static void write(Argument arg) throws Exception {
+		try {
+			Document document = DocumentHelper.createDocument();
+			// Element persistence = document.addElement("persistence",
+			// "http://java.sun.com/xml/ns/persistence");
+			// persistence.addAttribute(QName.get("schemaLocation", "xsi",
+			// "http://www.w3.org/2001/XMLSchema-instance"),
+			// "http://java.sun.com/xml/ns/persistence
+			// http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd");
+			// persistence.addAttribute("version", "2.0");
+
+			Element persistence = document.addElement("persistence", "http://java.sun.com/xml/ns/persistence");
+			persistence.addAttribute(QName.get("schemaLocation", "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
+					"http://java.sun.com/xml/ns/persistence  http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd");
+			persistence.addAttribute("version", "2.0");
+			Element unit = persistence.addElement("persistence-unit");
+			unit.addAttribute("name", "enhance");
+			Set<Class<?>> classes = new HashSet<>();
+			for (Class<?> o : scanEnhanceClass()) {
+				classes.addAll(scanMappedSuperclass(o));
+			}
+			for (Class<?> o : classes) {
+				Element element = unit.addElement("class");
+				element.addText(o.getCanonicalName());
+			}
+			OutputFormat format = OutputFormat.createPrettyPrint();
+			format.setEncoding("UTF-8");
+			XMLWriter writer = new XMLWriter(new FileWriter(new File(arg.getPath())), format);
+			writer.write(document);
+			writer.close();
+			System.out.println("create enhance persistence.xml at path:" + arg.getPath());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	private static List<Class<?>> scanEnhanceClass() throws Exception {
+		FastClasspathScanner scanner = new FastClasspathScanner(Packages.PREFIX);
+		ScanResult scanResult = scanner.scan();
+		List<Class<?>> sortedList = new ArrayList<Class<?>>();
+		for (String str : scanResult.getNamesOfClassesWithAnnotationsAnyOf(MappedSuperclass.class, Entity.class)) {
+			sortedList.add(Class.forName(str));
+		}
+		Collections.sort(sortedList, new Comparator<Class<?>>() {
+			public int compare(Class<?> c1, Class<?> c2) {
+				return c1.getCanonicalName().compareTo(c2.getCanonicalName());
+			}
+		});
+		return sortedList;
+	}
+
+	private static Set<Class<?>> scanMappedSuperclass(Class<?> clz) throws Exception {
+		Set<Class<?>> set = new HashSet<Class<?>>();
+		set.add(clz);
+		Class<?> s = clz.getSuperclass();
+		while (null != s) {
+			if (null != s.getAnnotation(MappedSuperclass.class)) {
+				set.add(s);
+			}
+			s = s.getSuperclass();
+		}
+		return set;
+	}
+
+	public class Argument {
+		private String path;
+
+		public String getPath() {
+			return path;
+		}
+
+		public void setPath(String path) {
+			this.path = path;
+		}
+	}
+}

+ 42 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/EntityManagerContainerTools.java

@@ -0,0 +1,42 @@
+package com.x.base.core.entity.tools;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.entity.JpaObject;
+
+public class EntityManagerContainerTools {
+
+	public static <T extends JpaObject> Integer batchDelete(EntityManagerContainer emc, Class<T> clz, Integer batchSize,
+			String... ids) throws Exception {
+		List<String> list = Arrays.asList(ids);
+		return batchDelete(emc, clz, batchSize, list);
+	}
+
+	public static <T extends JpaObject> Integer batchDelete(EntityManagerContainer emc, Class<T> clz, Integer batchSize,
+			List<String> ids) throws Exception {
+		if (null == batchSize || batchSize < 1 || null == ids || ids.isEmpty()) {
+			return 0;
+		}
+		Integer count = 0;
+		EntityManager em = emc.get(clz);
+		for (int i = 0; i < ids.size(); i++) {
+			if (i % batchSize == 0) {
+				em.getTransaction().begin();
+			}
+			T t = em.find(clz, ids.get(i));
+			if (null != t) {
+				em.remove(t);
+			}
+			if ((i % batchSize == (batchSize - 1)) || (i == ids.size() - 1)) {
+				em.getTransaction().commit();
+				count++;
+			}
+		}
+		return count;
+	}
+
+}

+ 135 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/JpaObjectTools.java

@@ -0,0 +1,135 @@
+package com.x.base.core.entity.tools;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Path;
+
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.openjpa.persistence.jdbc.ElementColumn;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.tools.StringTools;
+
+public class JpaObjectTools {
+	public static boolean isList(Path<?> path) throws Exception {
+		return List.class.isAssignableFrom(path.getJavaType());
+	}
+
+	public static <T extends JpaObject> Integer definedLength(Class<T> clz, String attribute) throws Exception {
+		Field field = FieldUtils.getField(clz, attribute, true);
+		return definedLength(clz, field);
+	}
+
+	public static <T extends JpaObject> Integer definedLength(Class<T> clz, Field field) throws Exception {
+		if (null == field) {
+			throw new Exception(
+					"can not find field with Class:" + clz + ", attribute:" + Objects.toString(field) + ".");
+		}
+		Integer length = null;
+		for (int i = 0; i < 1; i++) {
+			Column column = field.getAnnotation(Column.class);
+			if (null != column) {
+				length = column.length();
+				break;
+			}
+			ElementColumn elementColumn = field.getAnnotation(ElementColumn.class);
+			if (null != elementColumn) {
+				length = elementColumn.length();
+			}
+		}
+		if (null == length) {
+			throw new Exception("can not find @Column or @ElementColumn with Class:" + clz + ", attribute:"
+					+ Objects.toString(field) + ".");
+		}
+		return length;
+	}
+
+	public static <T extends JpaObject> boolean withinDefinedLength(String value, Class<T> clz, Field field)
+			throws Exception {
+		return StringTools.utf8Length(value) < definedLength(clz, field);
+	}
+
+	public static <T extends JpaObject> boolean withinDefinedLength(String value, Class<T> clz, String attribute)
+			throws Exception {
+		return StringTools.utf8Length(value) < definedLength(clz, attribute);
+	}
+
+	public static Date confirm(Date date) throws Exception {
+		return (date == null) ? null : new Date(date.getTime());
+	}
+
+	// /*
+	// * 在使用cb.isMember的情况下,将List<String> 转化为Expression<Set<String>>
+	// */
+	// public static <T extends JpaObject> Expression<Set<String>>
+	// stringValueListToIsMemberExpression(Class<T> cls,
+	// String attribute, CriteriaBuilder cb, List<String> values) throws Exception {
+	// HashMap<String, String> map = new HashMap<String, String>();
+	// StringTools.filterLessThanOrEqualToUtf8Length(values,
+	// JpaObjectTools.definedLength(cls, attribute))
+	// .forEach(o -> {
+	// map.put(o, o);
+	// });
+	// return cb.keys(map);
+	// }
+	
+	/* 根据一组一组对齐 */
+	public static <L extends JpaObject, R extends JpaObject> List<Pair<L, R>> align(List<L> lefts, List<R> rights,
+			boolean skipNull, boolean skipEmptyString, String... fields) throws Exception {
+		List<Pair<L, R>> list = new ArrayList<>();
+		List<L> find_lefts = new ArrayList<>();
+		List<R> find_rights = new ArrayList<>();
+		loop: for (L l : ListTools.trim(lefts, true, false)) {
+			for (R r : ListTools.trim(rights, true, false)) {
+				if (StringUtils.isNotEmpty(l.getId()) && StringUtils.equals(l.getId(), r.getId())) {
+					list.add(new ImmutablePair<>(l, r));
+					find_lefts.add(l);
+					find_rights.add(r);
+					continue loop;
+				}
+			}
+		}
+		for (String field : fields) {
+			loop: for (L l : ListUtils.subtract(ListTools.trim(lefts, true, false), find_lefts)) {
+				Object lo = l.get(field);
+				if (skipNull && (null == lo)) {
+					continue;
+				}
+				if (skipEmptyString && CharSequence.class.isAssignableFrom(lo.getClass())
+						&& (StringUtils.isEmpty(Objects.toString(lo, "")))) {
+					continue;
+				}
+				for (R r : ListUtils.subtract(ListTools.trim(rights, true, false), find_rights)) {
+					Object ro = r.get(field);
+					if (Objects.equals(lo, ro)) {
+						list.add(new ImmutablePair<>(l, r));
+						find_lefts.add(l);
+						find_rights.add(r);
+						continue loop;
+					}
+				}
+			}
+		}
+		for (L l : ListUtils.subtract(ListTools.trim(lefts, true, false), find_lefts)) {
+			list.add(new ImmutablePair<>(l, null));
+		}
+		for (R r : ListUtils.subtract(ListTools.trim(rights, true, false), find_rights)) {
+			list.add(new ImmutablePair<>(null, r));
+		}
+		return list;
+	}
+}

+ 125 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/PersistenceXmlWriter.java

@@ -0,0 +1,125 @@
+package com.x.base.core.entity.tools;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.persistence.MappedSuperclass;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.openjpa.persistence.PersistenceProviderImpl;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.QName;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+
+import com.x.base.core.project.tools.MainTools;
+
+public class PersistenceXmlWriter {
+
+	public static void main(String[] args) throws Exception {
+		Argument arg = MainTools.parseArgument(args[0], Argument.class);
+		write(arg);
+	}
+
+	private static void write(Argument arg) throws Exception {
+		try {
+			Document document = DocumentHelper.createDocument();
+			Element persistence = document.addElement("persistence", "http://java.sun.com/xml/ns/persistence");
+			persistence.addAttribute(QName.get("schemaLocation", "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
+					"http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd");
+			persistence.addAttribute("version", "2.0");
+			for (Class<?> cls : scanContainerEntity(arg.getProject())) {
+				Element unit = persistence.addElement("persistence-unit");
+				unit.addAttribute("name", cls.getCanonicalName());
+				unit.addAttribute("transaction-type", "RESOURCE_LOCAL");
+				Element provider = unit.addElement("provider");
+				provider.addText(PersistenceProviderImpl.class.getCanonicalName());
+				for (Class<?> o : scanMappedSuperclass(cls)) {
+					Element mapped_element = unit.addElement("class");
+					mapped_element.addText(o.getCanonicalName());
+				}
+				Element slice_unit_properties = unit.addElement("properties");
+				Map<String, String> properties = new LinkedHashMap<String, String>();
+				for (Entry<String, String> entry : properties.entrySet()) {
+					Element property = slice_unit_properties.addElement("property");
+					property.addAttribute("name", entry.getKey());
+					property.addAttribute("value", entry.getValue());
+				}
+			}
+			OutputFormat format = OutputFormat.createPrettyPrint();
+			format.setEncoding("UTF-8");
+			File file = new File(arg.getPath());
+			XMLWriter writer = new XMLWriter(new FileWriter(file), format);
+			writer.write(document);
+			writer.close();
+			System.out.println("create persistence.xml at path:" + arg.getPath());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private static List<Class<?>> scanContainerEntity(String project) throws Exception {
+		Set<Class<?>> ces = new HashSet<>();
+		String className = "com.x.base.core.project." + project;
+		Class<?> cls = Class.forName(className);
+		for (String str : (List<String>) FieldUtils.readStaticField(cls, "containerEntities")) {
+			if (StringUtils.isNotEmpty(str)) {
+				ces.add(Class.forName(str));
+			}
+		}
+		List<Class<?>> sortedList = new ArrayList<Class<?>>(ces);
+		Collections.sort(sortedList, new Comparator<Class<?>>() {
+			public int compare(Class<?> c1, Class<?> c2) {
+				return c1.getCanonicalName().compareTo(c2.getCanonicalName());
+			}
+		});
+		return sortedList;
+	}
+
+	private static Set<Class<?>> scanMappedSuperclass(Class<?> clz) throws Exception {
+		Set<Class<?>> set = new HashSet<Class<?>>();
+		set.add(clz);
+		Class<?> s = clz.getSuperclass();
+		while (null != s) {
+			if (null != s.getAnnotation(MappedSuperclass.class)) {
+				set.add(s);
+			}
+			s = s.getSuperclass();
+		}
+		return set;
+	}
+
+	public class Argument {
+		private String path;
+		private String project;
+
+		public String getPath() {
+			return path;
+		}
+
+		public void setPath(String path) {
+			this.path = path;
+		}
+
+		public String getProject() {
+			return project;
+		}
+
+		public void setProject(String project) {
+			this.project = project;
+		}
+	}
+}

+ 107 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/tools/SqlWriter.java

@@ -0,0 +1,107 @@
+package com.x.base.core.entity.tools;
+
+
+//public class SqlWriter {
+//	public static void main(String[] arguments) throws Exception {
+
+//		try {
+//			Document document = DocumentHelper.createDocument();
+//			Element persistence = document.addElement("persistence", "http://java.sun.com/xml/ns/persistence");
+//
+//			persistence.addAttribute(QName.get("schemaLocation", "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
+//					"http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd");
+//
+//			persistence.addAttribute("version", "2.0");
+//			Element persistence_unit_x = persistence.addElement("persistence-unit");
+//			persistence_unit_x.addAttribute("name", "x");
+//			persistence_unit_x.addAttribute("transaction-type", "RESOURCE_LOCAL");
+//			Element jta_data_source = persistence_unit_x.addElement("non-jta-data-source");
+//			jta_data_source.addText("jdbc/x");
+//
+//			Map<String, Set<String>> unitMap = new TreeMap<String, Set<String>>();
+//
+//			Reflections reflections = new Reflections("com.x.core.entity");
+//			Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(PersistenceXml.class);
+//			for (Class<?> clazz : classSet) {
+//				PersistenceXml persistenceXml = (PersistenceXml) clazz.getAnnotation(PersistenceXml.class);
+//				Set<String> set = unitMap.get(persistenceXml.unit());
+//				if (null == set) {
+//					set = new TreeSet<String>();
+//					unitMap.put(persistenceXml.unit(), set);
+//				}
+//				set.add(clazz.getName());
+//				boolean loop = false;
+//				Class<?> superClass = clazz.getSuperclass();
+//				do {
+//					loop = false;
+//					for (Class<?> cl : classSet) {
+//						if (cl.getName().equalsIgnoreCase(superClass.getName())) {
+//							loop = true;
+//							set.add(superClass.getName());
+//							superClass = superClass.getSuperclass();
+//							break;
+//						}
+//					}
+//				} while (loop);
+//			}
+//
+//			Set<String> union = new TreeSet<String>();
+//			for (String s : unitMap.keySet()) {
+//				Set<String> set = unitMap.get(s);
+//				for (String str : set) {
+//					union.add(str);
+//				}
+//			}
+//			for (String s : union) {
+//				Element el = persistence_unit_x.addElement("class");
+//				el.addText(s);
+//			}
+//
+//			Element persistence_unit_x_properties = persistence_unit_x.addElement("properties");
+//			Element unit_x_property_1 = persistence_unit_x_properties.addElement("property");
+//			unit_x_property_1.addAttribute("name", "openjpa.jdbc.DBDictionary");
+//			unit_x_property_1.addAttribute("value", "db2");
+//			Element unit_x_property_2 = persistence_unit_x_properties.addElement("property");
+//			unit_x_property_2.addAttribute("name", "openjpa.jdbc.SynchronizeMappings");
+//			unit_x_property_2.addAttribute("value", "buildSchema(ForeignKeys=false)");
+//			Element unit_x_property_3 = persistence_unit_x_properties.addElement("property");
+//			unit_x_property_3.addAttribute("name", "openjpa.Log");
+//			unit_x_property_3.addAttribute("value", "DefaultLevel=TRACE");
+//			Element unit_x_property_4 = persistence_unit_x_properties.addElement("property");
+//			unit_x_property_4.addAttribute("name", "openjpa.jdbc.Schema");
+//			unit_x_property_4.addAttribute("value", "x");
+//			Element unit_x_property_5 = persistence_unit_x_properties.addElement("property");
+//			unit_x_property_5.addAttribute("name", "openjpa.ConnectionDriverName");
+//			unit_x_property_5.addAttribute("value", "com.ibm.db2.jcc.DB2Driver");
+//			Element unit_x_property_6 = persistence_unit_x_properties.addElement("property");
+//			unit_x_property_6.addAttribute("name", "openjpa.ConnectionURL");
+//			unit_x_property_6.addAttribute("value", arguments[0]);
+//			Element unit_x_property_7 = persistence_unit_x_properties.addElement("property");
+//			unit_x_property_7.addAttribute("name", "openjpa.ConnectionUserName");
+//			unit_x_property_7.addAttribute("value", arguments[1]);
+//			Element unit_x_property_8 = persistence_unit_x_properties.addElement("property");
+//			unit_x_property_8.addAttribute("name", "openjpa.ConnectionPassword");
+//			unit_x_property_8.addAttribute("value", arguments[2]);
+//
+//			OutputFormat format = OutputFormat.createPrettyPrint();
+//			format.setEncoding("UTF-8");
+//			XMLWriter writer = new XMLWriter(new FileWriter("src/test/resources/META-INF/persistence.xml"), format);
+//			writer.write(document);
+//			writer.close();
+//			System.out.println("create new persistence.xml");
+//		} catch (Exception e) {
+//			e.printStackTrace();
+//		}
+//
+//		String[] args = new String[] {};
+//		Options opts = new Options();
+//		opts.put("schemaAction", arguments[3]);
+//		opts.put("sqlFile", "sql/" + arguments[3] + ".sql");
+//		JDBCConfiguration conf = new JDBCConfigurationImpl();
+//		try {
+//			MappingTool.run(conf, args, opts);
+//		} finally {
+//			conf.close();
+//		}
+//	}
+//}

+ 8 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/type/GenderType.java

@@ -0,0 +1,8 @@
+package com.x.base.core.entity.type;
+
+import com.x.base.core.entity.JpaObject;
+
+public enum GenderType {
+	f, m, d;
+	public static final int length=JpaObject.length_1B;
+}

+ 124 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/openjpa/jdbc/sql/DMDictionary.java

@@ -0,0 +1,124 @@
+package com.x.base.core.openjpa.jdbc.sql;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Set;
+
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+
+public class DMDictionary extends DBDictionary {
+	public static final String VENDOR_DAMENG = "dameng";
+	private static final Localizer _loc = Localizer.forPackage(DMDictionary.class);
+	private String schemaCase = "preserve";
+	public boolean uniqueIdentifierAsVarbinary = true;
+
+	public DMDictionary() {
+		this.platform = "dameng";
+		this.validationSQL = "SELECT GETDATE()";
+		this.supportsAutoAssign = true;
+		this.autoAssignClause = "IDENTITY";
+		this.lastGeneratedKeyQuery = "SELECT @@IDENTITY";
+		this.nextSequenceQuery = "SELECT {0}.NEXTVAL";
+		this.integerTypeName = "INT";
+		this.substringFunctionName = "SUBSTR";
+
+		this.reservedWordSet.addAll(Arrays.asList(new String[] { "ABORT", "ABSOLUTE", "ABSTRACT", "ACROSS", "ACTION",
+				"ADD", "AUDIT", "ADMIN", "AFTER", "ALL", "ALLOW_DATETIME", "ALLOW_IP", "ALTER", "ANALYZE", "AND", "ANY",
+				"ARCHIVEDIR", "ARCHIVELOG", "ARCHIVESTYLE", "ARRAY", "ARRAYLEN", "AS", "ASC", "ASSIGN", "AT", "ATTACH",
+				"AUTHORIZATION", "AUTO", "AUTOEXTEND", "AVG", "BACKUP", "BACKUPDIR", "BACKUPINFO", "BAKFILE", "BASE",
+				"BEFORE", "BEGIN", "BETWEEN", "BIGDATEDIFF", "BIGINT", "BINARY", "BIT", "BITMAP", "BLOB", "BLOCK",
+				"BOOL", "BOOLEAN", "BOTH", "BOUNDARY", "BRANCH", "BREAK", "BSTRING", "BTREE", "BY", "BYTE", "CACHE",
+				"CALL", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG", "CATCH", "CHAIN", "CHAR", "CHARACTER",
+				"CHECK", "CIPHER", "CLASS", "CLOB", "CLOSE", "CLUSTER", "CLUSTERBTR", "COLUMN", "COMMENT", "COMMIT",
+				"COMMITTED", "COMMITWORK", "COMPILE", "COMPRESS", "COMPRESSED", "CONNECT", "CONNECT_BY_IS_CYCLE",
+				"CONNECT_BY_IS_LEAF", "CONNECT_BY_ROOT", "CONNECT_IDLE_TIME", "CONST", "CONSTANT", "CONSER_OP",
+				"CONSTRAINT", "CONTAINS", "CONTEXT", "CONTINUE", "CONVERT", "COUNT", "CPU_REF_CALL", "CPU_REF_SESSION",
+				"CREATE", "CROSS", "CRYPTO", "CTLFILE", "CUBE", "CURRENT", "CURSOR", "CYCLE", "DANGLING", "DATABASE",
+				"DATAFILE", "DATE", "DATEADD", "DATEDIFF", "DATEPART", "DATETIME", "DAY", "DBFILE", "DEBUG", "DEC",
+				"DECIMAL", "DECLARE", "DECODE", "DEFAULT", "DEFERRABLE", "DELETE", "DELETING", "DEREF", "DESC",
+				"DETACH", "DISABLE", "DISCONNECT", "DISKSPACE", "DISTINCT", "DISTRIBUTED", "DO", "DOUBLE", "DOWN",
+				"DROP", "EACH", "ELSE", "ELSEIF", "ENABLE", "ENCRYPT", "ENCRYPTION", "END", "EQU", "ERROR", "ESCAPE",
+				"EVENTINFO", "EXCEPT", "EXCEPTION", "EXCHANGE", "EXCLUSIVE", "EXECUTE", "EXISTS", "EXIT", "EXPLAIN",
+				"EXTERN", "EXTERNAL", "EXTERNALLY", "EXTRACT", "FAILED_LOGIN_ATTEMPS", "FALSE", "FETCH", "FILEGROUP",
+				"FILLFACTOR", "FINALLY", "FIRST", "FLOAT", "FOR", "FORCE", "FOREIGN", "FREQUENCE", "FROM", "FULL",
+				"FUNCTION", "FOLLOWING", "GET", "GLOBAL", "GOTO", "GRANT", "GROUP GROUPING", "HASH", "HAVING",
+				"HEXTORAW", "HOUR", "IDENTIFIED", "IDENTITY", "IDENTITY_INSERT", "IF", "IMAGE", "IMMEDIATE", "IN",
+				"INCREASE", "INCREMENT", "INDEX", "INITIAL", "INITIALLY", "INNER", "INNERID", "INSERT", "INSERTING",
+				"INSTEAD", "INT", "INTEGER", "INTENT", "INTERNAL", "INTERSECT", "INTERVAL", "INTO", "IS", "ISOLATION",
+				"JAVA", "JOIN", "KEY", "LABEL", "LAST", "LEAD", "LEFT", "LESS", "LEVEL", "LEXER", "LIKE", "LIMIT",
+				"LINK", "LIST", "LOB", "LOCAL", "LOCK", "LOG", "LOGFILE", "LOGIN", "LOGOUT", "LONG", "LONGVARBINARY",
+				"LONGVARCHAR", "LOOP", "LP_OP", "LT_BINTEGER", "LT_BIGINTEGER", "LT_BITSTRING", "LT_DECIMAL",
+				"LT_GLOBAL_VAR", "LT_IDENTIFIER", "LT_INTEGER", "LP_REAL", "LT_STRING", "MANUAL", "MAP", "MATCH",
+				"MATCHED", "MAX", "MAXSIZE", "MAXVALUE", "MEMBER", "MEN_SPACE", "MERGE", "MIN", "MINEXTENTS", "MINUS",
+				"MINUTE", "MINVALUE", "MODE", "MODIFY", "MONEY", "MONTH", "MOUNT", "NATURAL", "NEW", "NEXT", "NO",
+				"NOARCHIVELOG", "NOAUDIT", "NOBRANCH", "NOCACHE", "NOCYCLE", "NOMAXVALUE", "NOMINVALUE", "NONE",
+				"NOORDER", "NORMAL", "NOSALT", "NOT", "NOT_ALLOW_DATETIME", "NOT_ALLOW_IP", "NOWAIT", "NULL", "",
+				"NUMBER", "NUMERIC", "OBJECT", "OF", "OFF", "OFFLINE", "OFFSET", "OLD", "ON", "ONCE", "ONLINE", "ONLY",
+				"OP_SHIFT_LERT", "OP_SHIFT_RIGHT", " OPEN", "OPTION", "OR", "ORDER", "OUT", "OUTER", "OVER ",
+				"OVERLAPS", "OVERRIDE", "PACKAGE", "PACKAGE_BODY", "PAGE", "PARTIAL", "PARTITION", "PARTITIONS",
+				"PASSWORD_GRACE_TIME", "PASSWORD_LIFE_TIME", "PASSWORD_LOCK_TIME", "PASSWORD_POLICY",
+				"PASSWORD_REUSE_MAX", "PASSWORD_REUSE_TIME", "PENDANT", "PERCENT", "PRECEDING", "PRECISION", "PRESERVE",
+				"PRIMARY", "PRINT", "PRIOR", "PRIVATE", "PRIVILEGES", "PROCEDURE", "PROTECTED", "PT_FOUND", "PT_ISOPEN",
+				"PT_NOFOUND", "PT_ROWCOUNT", "PT_ROWTYPE", "PT_TYPE", "PUBLIC", "PUT", "RAISE", "RANGE", "RAWTOHEX",
+				"READ", "READ_PER_CALL", "READ_PER_SESSION", "READONLY", "REAL", "REBUILD", "RECORD", "REF",
+				"REFERENCES", "REFERENCING", "RELATED", "RELATIVE", "RENAME", "REPEAT", "REPEATABLE", "REPLACE",
+				"REPLICATE", "RESIZE", "RESTORE", "RESTRICT", "RETURN", "RETURNING", "REVERSE", "REVOKE", "RIGHT",
+				"ROLE", "ROLLBACK", "ROLLFILE", "ROLLUP", "ROOT", "ROW", "ROWCOUNT", "ROWID", "ROWNUM", "ROWS", "RULE",
+				"SALT", "SAVEPOINT", "SBYTE", "SCHEMA", "SCOPE", "SEALED", "SECTION", "SECOND", "SELECT", "SELSTAR",
+				"SEQUENCE", "SERERR", "SERIALIZABLE", "SERVER", "SESSION_PER_USER", "SET", "SETS", "SHARE", "SHORT",
+				"SHUTDOWN", "SIBLINGS", "SIZE", "SIZEOF", "SMALLINT", "SNAPSHOT", "SOME", "SOUND", "SPLIT", "SQL",
+				"STANDBY", "START_WITH", "STARTUP", "STATEMENT", "STATIC", "STAT", "STDDEV", "STORAGE", "STORE",
+				"STRING", "STRUCT", "STYLE", "SUBSTRING", "SUCCESSFUL", "SUM", "SUSPEND", "SWITCH", "SYNC", "SYNONYM",
+				"SYS_CONNECT_BY_PATH", "TABLE", "TABLESPACE", "TEMPORARY", "TEXT", "THAN", "THEN", "THROW", "TIES",
+				"TIME", "TIMER", "TIMES", "TIMESTAMP", "TIMESTAMPADD", "TIMESTAMPDIFF", "TINYINT", "TO",
+				"TOO_MANY_ROWS", "TOP", "TRAIL", "TRANSACTION", "TRANSACTIONAL", "TRIGGER", "TRIGGERS", "TRIM", "TRUE",
+				"TRUNCATE", "TRUNCSIZE", "TRY", "TYPE", "TYPE_BODY", "TYPEOF", "UINT", "ULONG", "UNBOUNDED",
+				"UNCOMMITTED", "UNDER", "UNION", "UNIQUE", "UNLIMITED", "UNSAFE", "UNTIL", "UP", "UPDATE", "UPDATING",
+				"USER", "USHORT", "USING", "VALUE", "VALUES", "VARBINARY", "VARCHAR", "VARCHAR2", "VARIANCE", "VARYING",
+				"VERIFY", "VERTICAL", "VIEW", "VIRTUAL", "VOID", "VOLATILE", "VSIZE", "WEEK", "WHEN", "WHENEVER",
+				"WHERE", "WHILE", "WITH", "WORK", "WRAPPED", "WRITE", "YEAR", "ZONE" }));
+		this.systemSchemaSet.addAll(Arrays.asList(new String[] { "CTISYS", "SYS", "SYSDBA", "SYSSSO", "SYSAUDITOR" }));
+		this.fixedSizeTypeNameSet
+				.addAll(Arrays.asList(new String[] { "IMAGE", "TEXT", "DATETIME", "LONGVARBINARY", "LONGVARCHAR" }));
+
+		this.supportsDeferredConstraints = true;
+		this.supportsSelectEndIndex = true;
+	}
+
+	protected void appendSelectRange(SQLBuffer buf, long start, long end, boolean subselect) {
+		buf.append(" LIMIT ").appendValue(start).append(", ").appendValue(end - start);
+	}
+
+	public void connectedConfiguration(Connection conn) throws SQLException {
+		super.connectedConfiguration(conn);
+		boolean requiresWarnings = true;
+		DatabaseMetaData meta = conn.getMetaData();
+		String driverName = meta.getDriverName();
+		String url = meta.getURL();
+		if (this.driverVendor == null) {
+			if ((driverName != null) && (driverName.equalsIgnoreCase("dm.jdbc.driver.DmDriver"))) {
+				this.driverVendor = "Dm7JdbcDriver";
+				if ((url != null) && (url.startsWith("jdbc:dm://"))) {
+					requiresWarnings = false;
+				}
+			} else {
+				this.driverVendor = "other";
+			}
+		}
+		if (("Dm7JdbcDriver".equalsIgnoreCase(this.driverVendor)) && (requiresWarnings)) {
+			this.log.warn(_loc.get("Dm Jdbc connection", url));
+		}
+	}
+
+	public Date getDate(ResultSet rs, int column) throws SQLException {
+		return rs.getDate(column);
+	}
+}

+ 13 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/AbstractContext.java

@@ -0,0 +1,13 @@
+package com.x.base.core.project;
+
+public abstract class AbstractContext {
+	/** Applications资源 */
+	protected volatile Applications applications;
+
+	public Applications applications() {
+		synchronized (this) {
+			return this.applications;
+		}
+	}
+
+}

+ 120 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Application.java

@@ -0,0 +1,120 @@
+package com.x.base.core.project;
+
+import java.util.Date;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.gson.GsonPropertyObject;
+
+public class Application extends GsonPropertyObject {
+
+	private String name;
+	private String node;
+	private String context;
+	private Integer port;
+	private String token;
+	private Boolean sslEnable;
+
+	private String proxyHost;
+	private Integer proxyPort;
+
+	private Integer weight;
+
+	private Date reportDate;
+
+	public String getUrlRoot() {
+		StringBuffer buffer = new StringBuffer();
+		if (BooleanUtils.isTrue(this.sslEnable)) {
+			buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
+					.append(port == 443 ? "" : (":" + port));
+		} else {
+			buffer.append("http://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
+					.append(port == 80 ? "" : (":" + port));
+		}
+		buffer.append(context + "/jaxrs/");
+		return buffer.toString();
+
+	}
+
+	public Integer getPort() {
+		return port;
+	}
+
+	public void setPort(Integer port) {
+		this.port = port;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+	public Integer getWeight() {
+		return weight;
+	}
+
+	public void setWeight(Integer weight) {
+		this.weight = weight;
+	}
+
+	public Date getReportDate() {
+		return reportDate;
+	}
+
+	public void setReportDate(Date reportDate) {
+		this.reportDate = reportDate;
+	}
+
+	public String getContext() {
+		return context;
+	}
+
+	public void setContext(String context) {
+		this.context = context;
+	}
+
+	public void setProxyPort(Integer proxyPort) {
+		this.proxyPort = proxyPort;
+	}
+
+	public void setProxyHost(String proxyHost) {
+		this.proxyHost = proxyHost;
+	}
+
+	public String getProxyHost() {
+		return proxyHost;
+	}
+
+	public Integer getProxyPort() {
+		return proxyPort;
+	}
+
+	public Boolean getSslEnable() {
+		return sslEnable;
+	}
+
+	public void setSslEnable(Boolean sslEnable) {
+		this.sslEnable = sslEnable;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getNode() {
+		return node;
+	}
+
+	public void setNode(String node) {
+		this.node = node;
+	}
+
+}

+ 218 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Applications.java

@@ -0,0 +1,218 @@
+package com.x.base.core.project;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.connection.ActionResponse;
+import com.x.base.core.project.connection.CipherConnectionAction;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.DefaultCharset;
+import com.x.base.core.project.tools.StringTools;
+
+public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList<Application>> {
+
+	private static Logger logger = LoggerFactory.getLogger(Applications.class);
+
+	private static final long serialVersionUID = -2416559829493154858L;
+
+	private volatile String token = UUID.randomUUID().toString();
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+	public Application get(Class<?> clz, String token) throws Exception {
+		List<Application> list = this.get(clz.getName());
+		if (null != list) {
+			for (Application application : list) {
+				if (StringUtils.equals(token, application.getToken())) {
+					return application;
+				}
+			}
+		}
+		return null;
+	}
+
+	public List<Application> get(Class<?> clz) throws Exception {
+		return this.get(clz.getName());
+	}
+
+	public void add(Class<?> applicationClass, Application application) throws Exception {
+		CopyOnWriteArrayList<Application> list = this.get(applicationClass.getName());
+		if (null == list) {
+			list = new CopyOnWriteArrayList<Application>();
+			this.put(applicationClass.getName(), list);
+		}
+		list.add(application);
+	}
+
+	public ActionResponse getQuery(Boolean xdebugger, Class<?> applicationClass, String uri) throws Exception {
+		Application application = this.randomWithWeight(applicationClass);
+		return CipherConnectionAction.get(xdebugger, application.getUrlRoot() + CipherConnectionAction.trim(uri));
+	}
+
+	public ActionResponse getQuery(Class<?> applicationClass, String uri) throws Exception {
+		return this.getQuery(false, applicationClass, uri);
+	}
+
+	public ActionResponse getQuery(Boolean xdebugger, Application application, String uri) throws Exception {
+		return CipherConnectionAction.get(xdebugger,
+				StringTools.JoinUrl(application.getUrlRoot(), CipherConnectionAction.trim(uri)));
+	}
+
+	public ActionResponse getQuery(Application application, String uri) throws Exception {
+		return this.getQuery(false, application, uri);
+	}
+
+	public ActionResponse getQuery(Boolean xdebugger, String applicationName, String uri) throws Exception {
+		Class<?> cls = Class.forName(Applications.class.getPackage().getName() + "." + applicationName);
+		return this.getQuery(xdebugger, cls, uri);
+	}
+
+	public ActionResponse getQuery(String applicationName, String uri) throws Exception {
+		Class<?> cls = Class.forName(Applications.class.getPackage().getName() + "." + applicationName);
+		return this.getQuery(false, cls, uri);
+	}
+
+	public ActionResponse deleteQuery(Boolean xdebugger, Class<?> applicationClass, String uri) throws Exception {
+		Application application = this.randomWithWeight(applicationClass);
+		return CipherConnectionAction.delete(xdebugger,
+				StringTools.JoinUrl(application.getUrlRoot() + CipherConnectionAction.trim(uri)));
+	}
+
+	public ActionResponse deleteQuery(Class<?> applicationClass, String uri) throws Exception {
+		return this.deleteQuery(false, applicationClass, uri);
+	}
+
+	public ActionResponse deleteQuery(Boolean xdebugger, Application application, String uri) throws Exception {
+		return CipherConnectionAction.delete(xdebugger, application.getUrlRoot() + CipherConnectionAction.trim(uri));
+	}
+
+	public ActionResponse deleteQuery(Application application, String uri) throws Exception {
+		return this.deleteQuery(false, application, uri);
+	}
+
+	public ActionResponse deleteQuery(Boolean xdebugger, String applicationName, String uri) throws Exception {
+		Class<?> cls = Class.forName(Applications.class.getPackage().getName() + "." + applicationName);
+		return this.deleteQuery(xdebugger, cls, uri);
+	}
+
+	public ActionResponse deleteQuery(String applicationName, String uri) throws Exception {
+		Class<?> cls = Class.forName(Applications.class.getPackage().getName() + "." + applicationName);
+		return this.deleteQuery(false, cls, uri);
+	}
+
+	public ActionResponse postQuery(Boolean xdebugger, Class<?> applicationClass, String uri, Object o)
+			throws Exception {
+		Application application = this.randomWithWeight(applicationClass);
+		return CipherConnectionAction.post(xdebugger,
+				StringTools.JoinUrl(application.getUrlRoot() + CipherConnectionAction.trim(uri)), o);
+	}
+
+	public ActionResponse postQuery(Class<?> applicationClass, String uri, Object o) throws Exception {
+		return this.postQuery(false, applicationClass, uri, o);
+	}
+
+	public ActionResponse postQuery(Boolean xdebugger, Application application, String uri, Object o) throws Exception {
+		return CipherConnectionAction.post(xdebugger, application.getUrlRoot() + CipherConnectionAction.trim(uri), o);
+	}
+
+	public ActionResponse postQuery(Application application, String uri, Object o) throws Exception {
+		return this.postQuery(false, application, uri, o);
+	}
+
+	public ActionResponse postQuery(Boolean xdebugger, String applicationName, String uri, String body)
+			throws Exception {
+		Class<?> cls = Class.forName(Applications.class.getPackage().getName() + "." + applicationName);
+		return this.postQuery(xdebugger, cls, uri, body);
+	}
+
+	public ActionResponse postQuery(String applicationName, String uri, String body) throws Exception {
+		Class<?> cls = Class.forName(Applications.class.getPackage().getName() + "." + applicationName);
+		return this.postQuery(false, cls, uri, body);
+	}
+
+	public ActionResponse putQuery(Boolean xdebugger, Class<?> applicationClass, String uri, Object o)
+			throws Exception {
+		Application application = this.randomWithWeight(applicationClass);
+		return CipherConnectionAction.put(xdebugger, application.getUrlRoot() + CipherConnectionAction.trim(uri), o);
+	}
+
+	public ActionResponse putQuery(Class<?> applicationClass, String uri, Object o) throws Exception {
+		return this.putQuery(false, applicationClass, uri, o);
+	}
+
+	public ActionResponse putQuery(Boolean xdebugger, Application application, String uri, Object o) throws Exception {
+		return CipherConnectionAction.put(xdebugger,
+				StringTools.JoinUrl(application.getUrlRoot() + CipherConnectionAction.trim(uri)), o);
+	}
+
+	public ActionResponse putQuery(Application application, String uri, Object o) throws Exception {
+		return this.putQuery(false, application, uri, o);
+	}
+
+	public ActionResponse putQuery(Boolean xdebugger, String applicationName, String uri, String body)
+			throws Exception {
+		Class<?> cls = Class.forName(Applications.class.getPackage().getName() + "." + applicationName);
+		return this.putQuery(xdebugger, cls, uri, body);
+	}
+
+	public ActionResponse putQuery(String applicationName, String uri, String body) throws Exception {
+		Class<?> cls = Class.forName(Applications.class.getPackage().getName() + "." + applicationName);
+		return this.putQuery(false, cls, uri, body);
+	}
+
+	public Application randomWithWeight(Class<?> clz) throws Exception {
+		List<Application> availabeApplications = new ArrayList<>();
+		List<Application> list = this.get(clz.getName());
+		if (null != list) {
+			for (Application app : list) {
+				availabeApplications.add(app);
+			}
+		}
+		if (availabeApplications.isEmpty()) {
+			return null;
+		}
+		int total = 0;
+		for (Application application : availabeApplications) {
+			total += application.getWeight();
+		}
+		Random random = new Random();
+		int rdm = random.nextInt(total);
+		int current = 0;
+		for (Application application : availabeApplications) {
+			current += application.getWeight();
+			if (rdm <= current) {
+				return application;
+			}
+		}
+		throw new Exception("randomWithWeight error.");
+	}
+
+	public static String joinQueryUri(String... parts) {
+		return Stream.of(parts).map(s -> {
+			try {
+				return URLEncoder.encode(s, DefaultCharset.name);
+			} catch (UnsupportedEncodingException e) {
+				e.printStackTrace();
+				return "";
+			}
+		}).collect(Collectors.joining("/"));
+	}
+
+}

+ 148 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/AssembleA.java

@@ -0,0 +1,148 @@
+package com.x.base.core.project;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+
+import com.x.base.core.project.tools.JarTools;
+
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
+
+public abstract class AssembleA extends Deployable {
+
+	public static <T extends AssembleA> List<Class<T>> dependWith(Class<?> cls) throws Exception {
+		List<Class<T>> os = new ArrayList<>();
+		ScanResult scan = new FastClasspathScanner(AssembleA.class.getPackage().getName()).scan();
+		List<String> names = scan.getNamesOfSubclassesOf(AssembleA.class);
+		for (String name : names) {
+			Class<T> c = (Class<T>) Class.forName(name);
+			List<Class<?>> dependents = (List<Class<?>>) FieldUtils.readStaticField(c, "dependents");
+			if (dependents.contains(cls)) {
+				os.add(c);
+			}
+		}
+		return os;
+	}
+
+	private File concreteStructure(String distPath, String repositoryPath) throws Exception {
+		File dir = new File(distPath, this.getName());
+		FileUtils.forceMkdir(dir);
+		FileUtils.cleanDirectory(dir);
+		File webInf = new File(dir, "WEB-INF");
+		FileUtils.forceMkdir(webInf);
+		File lib = new File(webInf, "lib");
+		FileUtils.forceMkdir(lib);
+		File classes = new File(webInf, "classes");
+		FileUtils.forceMkdir(classes);
+		File metaInf = new File(classes, "META-INF");
+		FileUtils.forceMkdir(metaInf);
+		this.copyPersistence(metaInf, repositoryPath);
+		this.copyJar(lib, repositoryPath);
+		this.extractZip(dir, repositoryPath);
+		this.createWebXml(webInf);
+		return dir;
+	}
+
+	// private void createCenterServerFile(File metaInf, String host, Integer
+	// port, String cipher) throws Exception {
+	// TreeMap<String, Object> map = new TreeMap<>();
+	// map.put("host", StringUtils.trimToEmpty(host));
+	// map.put("port", null != port ? port : 30080);
+	// map.put("cipher", cipher);
+	// FileUtils.writeStringToFile(new File(metaInf, "centerServer.json"),
+	// XGsonBuilder.toJson(map));
+	// }
+	//
+	// private void createConfigFile(File metaInf, String
+	// configApplicationServer) throws Exception {
+	// TreeMap<String, Object> map = new TreeMap<>();
+	// map.put("applicationServer",
+	// StringUtils.trimToEmpty(configApplicationServer));
+	// FileUtils.writeStringToFile(new File(metaInf, "config.json"),
+	// XGsonBuilder.toJson(map));
+	// }
+
+	private void copyJar(File lib, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_base_core*.jar"));
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_common_core*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "openjpa"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "ehcache"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "slf4j"), lib, new WildcardFileFilter("*.jar"));
+	}
+
+	private void copyPersistence(File metaInf, String repositoryPath) throws Exception {
+		FileUtils.copyFile(new File(repositoryPath, "x_persistence_" + this.getName() + ".xml"),
+				new File(metaInf, "x_persistence.xml"), false);
+	}
+
+	private void createWebXml(File webInf) throws Exception {
+		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<web-app id=\"" + this.getName()
+				+ "\" metadata-complete=\"false\" version=\"3.0\">" + "<display-name>" + this.getName()
+				+ "</display-name>";
+		// xml += druid_servlet;
+		// xml += druid_servlet_mapping;
+		// xml += druid_filter;
+		// xml += druid_filter_mapping;
+		xml += "</web-app>";
+		File file = new File(webInf, "web.xml");
+		FileUtils.writeStringToFile(file, xml, "UTF-8");
+	}
+
+	// private void extractJar(File classes, String repositoryPath) throws
+	// Exception {
+	// File repositoryLib = new File(repositoryPath);
+	// Collection<File> files = FileUtils.listFiles(repositoryLib,
+	// new WildcardFileFilter(this.getName() + "-4.0.0.jar"), null);
+	// JarTools.unjar(files.iterator().next(), "", classes, true);
+	// }
+
+	private void extractZip(File dir, String repositoryPath) throws Exception {
+		File file = new File(repositoryPath, this.getName() + ".zip");
+		JarTools.unjar(file, "", dir, true);
+	}
+
+	@Override
+	public String pack(String distPath, String repositoryPath) throws Exception {
+		File dir = this.concreteStructure(distPath, repositoryPath);
+		custom(dir, repositoryPath);
+		File war = new File(distPath, this.getName() + ".war");
+		JarTools.jar(dir, war);
+		return war.getAbsolutePath();
+	}
+
+	protected abstract void custom(File dir, String repositoryPath) throws Exception;
+
+	protected String getName() {
+		return StringUtils.replace(this.getClass().getSimpleName(), ".", "_");
+	}
+
+	public class Argument {
+
+		private String distPath;
+		private String repositoryPath;
+
+		public String getDistPath() {
+			return distPath;
+		}
+
+		public void setDistPath(String distPath) {
+			this.distPath = distPath;
+		}
+
+		public String getRepositoryPath() {
+			return repositoryPath;
+		}
+
+		public void setRepositoryPath(String repositoryPath) {
+			this.repositoryPath = repositoryPath;
+		}
+
+	}
+}

+ 126 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/AssembleC.java

@@ -0,0 +1,126 @@
+package com.x.base.core.project;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.tools.JarTools;
+
+public abstract class AssembleC extends Deployable {
+
+	private File concreteStructure(String distPath, String repositoryPath) throws Exception {
+		File dir = new File(distPath, this.getName());
+		FileUtils.forceMkdir(dir);
+		FileUtils.cleanDirectory(dir);
+		File webInf = new File(dir, "WEB-INF");
+		FileUtils.forceMkdir(webInf);
+		File lib = new File(webInf, "lib");
+		FileUtils.forceMkdir(lib);
+		File classes = new File(webInf, "classes");
+		FileUtils.forceMkdir(classes);
+		File metaInf = new File(classes, "META-INF");
+		FileUtils.forceMkdir(metaInf);
+		this.copyPersistence(metaInf, repositoryPath);
+		this.copyJar(lib, repositoryPath);
+		this.extractZip(dir, repositoryPath);
+		this.createWebXml(webInf);
+		return dir;
+	}
+
+	// private void createCenterServerFile(File metaInf, String host, Integer
+	// port, String cipher) throws Exception {
+	// TreeMap<String, Object> map = new TreeMap<>();
+	// map.put("host", StringUtils.trimToEmpty(host));
+	// map.put("port", null != port ? port : 30080);
+	// map.put("cipher", cipher);
+	// FileUtils.writeStringToFile(new File(metaInf, "centerServer.json"),
+	// XGsonBuilder.toJson(map));
+	// }
+	//
+	// private void createConfigFile(File metaInf, String
+	// configApplicationServer) throws Exception {
+	// TreeMap<String, Object> map = new TreeMap<>();
+	// map.put("applicationServer",
+	// StringUtils.trimToEmpty(configApplicationServer));
+	// FileUtils.writeStringToFile(new File(metaInf, "config.json"),
+	// XGsonBuilder.toJson(map));
+	// }
+
+	private void copyJar(File lib, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_base_core*.jar"));
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_common_core*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "openjpa"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "ehcache"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "slf4j"), lib, new WildcardFileFilter("*.jar"));
+	}
+
+	private void copyPersistence(File metaInf, String repositoryPath) throws Exception {
+		FileUtils.copyFile(new File(repositoryPath, "x_persistence_" + this.getName() + ".xml"),
+				new File(metaInf, "x_persistence.xml"), false);
+	}
+
+	private void createWebXml(File webInf) throws Exception {
+		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<web-app id=\"" + this.getName()
+				+ "\" metadata-complete=\"false\" version=\"3.0\">" + "<display-name>" + this.getName()
+				+ "</display-name>";
+		// xml += druid_servlet;
+		// xml += druid_servlet_mapping;
+		// xml += druid_filter;
+		// xml += druid_filter_mapping;
+		xml += "</web-app>";
+		File file = new File(webInf, "web.xml");
+		FileUtils.writeStringToFile(file, xml, "UTF-8");
+	}
+
+	// private void extractJar(File classes, String repositoryPath) throws
+	// Exception {
+	// File repositoryLib = new File(repositoryPath);
+	// Collection<File> files = FileUtils.listFiles(repositoryLib,
+	// new WildcardFileFilter(this.getName() + "-4.0.0.jar"), null);
+	// JarTools.unjar(files.iterator().next(), "", classes, true);
+	// }
+
+	private void extractZip(File dir, String repositoryPath) throws Exception {
+		File file = new File(repositoryPath, this.getName() + ".zip");
+		JarTools.unjar(file, "", dir, true);
+	}
+
+	@Override
+	public String pack(String distPath, String repositoryPath) throws Exception {
+		File dir = this.concreteStructure(distPath, repositoryPath);
+		// custom(dir, repositoryPath);
+		File war = new File(distPath, this.getName() + ".war");
+		JarTools.jar(dir, war);
+		return war.getAbsolutePath();
+	}
+
+	protected String getName() {
+		return StringUtils.replace(this.getClass().getSimpleName(), ".", "_");
+	}
+
+	public class Argument {
+
+		private String distPath;
+		private String repositoryPath;
+
+		public String getDistPath() {
+			return distPath;
+		}
+
+		public void setDistPath(String distPath) {
+			this.distPath = distPath;
+		}
+
+		public String getRepositoryPath() {
+			return repositoryPath;
+		}
+
+		public void setRepositoryPath(String repositoryPath) {
+			this.repositoryPath = repositoryPath;
+		}
+
+	}
+}

+ 126 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/AssembleM.java

@@ -0,0 +1,126 @@
+package com.x.base.core.project;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.tools.JarTools;
+
+public abstract class AssembleM extends Deployable {
+
+	private File concreteStructure(String distPath, String repositoryPath) throws Exception {
+		File dir = new File(distPath, this.getName());
+		FileUtils.forceMkdir(dir);
+		FileUtils.cleanDirectory(dir);
+		File webInf = new File(dir, "WEB-INF");
+		FileUtils.forceMkdir(webInf);
+		File lib = new File(webInf, "lib");
+		FileUtils.forceMkdir(lib);
+		File classes = new File(webInf, "classes");
+		FileUtils.forceMkdir(classes);
+		File metaInf = new File(classes, "META-INF");
+		FileUtils.forceMkdir(metaInf);
+		this.copyPersistence(metaInf, repositoryPath);
+		this.copyJar(lib, repositoryPath);
+		this.extractZip(dir, repositoryPath);
+		this.createWebXml(webInf);
+		return dir;
+	}
+
+	// private void createCenterServerFile(File metaInf, String host, Integer
+	// port, String cipher) throws Exception {
+	// TreeMap<String, Object> map = new TreeMap<>();
+	// map.put("host", StringUtils.trimToEmpty(host));
+	// map.put("port", null != port ? port : 30080);
+	// map.put("cipher", cipher);
+	// FileUtils.writeStringToFile(new File(metaInf, "centerServer.json"),
+	// XGsonBuilder.toJson(map));
+	// }
+	//
+	// private void createConfigFile(File metaInf, String
+	// configApplicationServer) throws Exception {
+	// TreeMap<String, Object> map = new TreeMap<>();
+	// map.put("applicationServer",
+	// StringUtils.trimToEmpty(configApplicationServer));
+	// FileUtils.writeStringToFile(new File(metaInf, "config.json"),
+	// XGsonBuilder.toJson(map));
+	// }
+
+	private void copyJar(File lib, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_base_core*.jar"));
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_common_core*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "openjpa"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "ehcache"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "slf4j"), lib, new WildcardFileFilter("*.jar"));
+	}
+
+	private void copyPersistence(File metaInf, String repositoryPath) throws Exception {
+		FileUtils.copyFile(new File(repositoryPath, "x_persistence_" + this.getName() + ".xml"),
+				new File(metaInf, "x_persistence.xml"), false);
+	}
+
+	private void createWebXml(File webInf) throws Exception {
+		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<web-app id=\"" + this.getName()
+				+ "\" metadata-complete=\"false\" version=\"3.0\">" + "<display-name>" + this.getName()
+				+ "</display-name>";
+		// xml += druid_servlet;
+		// xml += druid_servlet_mapping;
+		// xml += druid_filter;
+		// xml += druid_filter_mapping;
+		xml += "</web-app>";
+		File file = new File(webInf, "web.xml");
+		FileUtils.writeStringToFile(file, xml, "UTF-8");
+	}
+
+	// private void extractJar(File classes, String repositoryPath) throws
+	// Exception {
+	// File repositoryLib = new File(repositoryPath);
+	// Collection<File> files = FileUtils.listFiles(repositoryLib,
+	// new WildcardFileFilter(this.getName() + "-4.0.0.jar"), null);
+	// JarTools.unjar(files.iterator().next(), "", classes, true);
+	// }
+
+	private void extractZip(File dir, String repositoryPath) throws Exception {
+		File file = new File(repositoryPath, this.getName() + ".zip");
+		JarTools.unjar(file, "", dir, true);
+	}
+
+	@Override
+	public String pack(String distPath, String repositoryPath) throws Exception {
+		File dir = this.concreteStructure(distPath, repositoryPath);
+		//custom(dir, repositoryPath);
+		File war = new File(distPath, this.getName() + ".war");
+		JarTools.jar(dir, war);
+		return war.getAbsolutePath();
+	}
+
+	protected String getName() {
+		return StringUtils.replace(this.getClass().getSimpleName(), ".", "_");
+	}
+
+	public class Argument {
+
+		private String distPath;
+		private String repositoryPath;
+
+		public String getDistPath() {
+			return distPath;
+		}
+
+		public void setDistPath(String distPath) {
+			this.distPath = distPath;
+		}
+
+		public String getRepositoryPath() {
+			return repositoryPath;
+		}
+
+		public void setRepositoryPath(String repositoryPath) {
+			this.repositoryPath = repositoryPath;
+		}
+
+	}
+}

+ 22 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Compilable.java

@@ -0,0 +1,22 @@
+package com.x.base.core.project;
+
+import java.io.File;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+
+public abstract class Compilable {
+
+	public static final String VERSION = "4.0.0";
+
+	public void compile(String projectPath, String name) throws Exception {
+		File buildFile = new File(projectPath, name + "_build.xml");
+		Project p = new Project();
+		p.setUserProperty("ant.file", buildFile.getAbsolutePath());
+		p.init();
+		ProjectHelper helper = ProjectHelper.getProjectHelper();
+		p.addReference("ant.projectHelper", helper);
+		helper.parse(p, buildFile);
+		p.executeTarget(p.getDefaultTarget());
+	}
+}

+ 48 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Compile.java

@@ -0,0 +1,48 @@
+package com.x.base.core.project;
+
+import java.io.File;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+
+import com.x.base.core.project.tools.MainTools;
+
+public class Compile {
+	public static void main(String[] args) throws Exception {
+		Argument arg = MainTools.parseArgument(args[0], Argument.class);
+		compile(arg.getName(), arg.getProjectPath());
+	}
+
+	public static void compile(String name, String projectPath) throws Exception {
+		File buildFile = new File(projectPath, name + "_build.xml");
+		Project antProject = new Project();
+		antProject.setBasedir(projectPath);
+		antProject.setUserProperty("ant.file", buildFile.getAbsolutePath());
+		antProject.init();
+		ProjectHelper helper = ProjectHelper.getProjectHelper();
+		antProject.addReference("ant.projectHelper", helper);
+		helper.parse(antProject, buildFile);
+		antProject.executeTarget(antProject.getDefaultTarget());
+	}
+
+	public class Argument {
+		private String name;
+		private String projectPath;
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public String getProjectPath() {
+			return projectPath;
+		}
+
+		public void setProjectPath(String projectPath) {
+			this.projectPath = projectPath;
+		}
+	}
+}

+ 125 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/CompileA.java

@@ -0,0 +1,125 @@
+package com.x.base.core.project;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.ListTools;
+
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
+
+public class CompileA {
+	public static void main(String[] args) throws Exception {
+		String str = StringUtils.replace(args[0], "\\", "/");
+		Argument arg = XGsonBuilder.instance().fromJson(str, Argument.class);
+		compileAll(arg);
+
+	}
+
+	public static void compileAll(Argument arg) throws Exception {
+		ScanResult scanResult = new FastClasspathScanner(Packages.PREFIX).scan();
+		if (arg.getIncludeCore()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(CoreA.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+		if (arg.getIncludeService()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(ServiceA.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+		if (arg.getIncludeAssemble()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(AssembleA.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+//		if (arg.includeCenter) {
+//			String name = x_program_center.class.getSimpleName();
+//			System.out.println("compile name:" + name + ".");
+//			Compile.compile(name, arg.getRootPath() + "/" + name);
+//		}
+	}
+
+	public class Argument {
+
+		private String rootPath;
+		private Boolean includeAssemble;
+		private Boolean includeCore;
+		private Boolean includeService;
+	//private Boolean includeCenter;
+
+		private List<String> excludes;
+
+		public Boolean getIncludeAssemble() {
+			return includeAssemble;
+		}
+
+		public void setIncludeAssemble(Boolean includeAssemble) {
+			this.includeAssemble = includeAssemble;
+		}
+
+		public Boolean getIncludeCore() {
+			return includeCore;
+		}
+
+		public void setIncludeCore(Boolean includeCore) {
+			this.includeCore = includeCore;
+		}
+
+		public Boolean getIncludeService() {
+			return includeService;
+		}
+
+		public void setIncludeService(Boolean includeService) {
+			this.includeService = includeService;
+		}
+//
+//		public Boolean getIncludeCenter() {
+//			return includeCenter;
+//		}
+//
+//		public void setIncludeCenter(Boolean includeCenter) {
+//			this.includeCenter = includeCenter;
+//		}
+
+		public String getRootPath() {
+			return rootPath;
+		}
+
+		public void setRootPath(String rootPath) {
+			this.rootPath = rootPath;
+		}
+
+		public List<String> getExcludes() {
+			return excludes;
+		}
+
+		public void setExcludes(List<String> excludes) {
+			this.excludes = excludes;
+		}
+
+	}
+}

+ 116 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/CompileC.java

@@ -0,0 +1,116 @@
+package com.x.base.core.project;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.ListTools;
+
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
+
+public class CompileC {
+	public static void main(String[] args) throws Exception {
+		String str = StringUtils.replace(args[0], "\\", "/");
+		Argument arg = XGsonBuilder.instance().fromJson(str, Argument.class);
+		compileAll(arg);
+
+	}
+
+	public static void compileAll(Argument arg) throws Exception {
+		ScanResult scanResult = new FastClasspathScanner(Packages.PREFIX).scan();
+		if (arg.getIncludeCore()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(CoreC.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+		if (arg.getIncludeService()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(ServiceC.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+		if (arg.getIncludeAssemble()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(AssembleC.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+		// if (arg.includeCenter) {
+		// String name = x_program_center.class.getSimpleName();
+		// System.out.println("compile name:" + name + ".");
+		// Compile.compile(name, arg.getRootPath() + "/" + name);
+		// }
+	}
+
+	public class Argument {
+
+		private String rootPath;
+		private Boolean includeAssemble;
+		private Boolean includeCore;
+		private Boolean includeService;
+
+		private List<String> excludes;
+
+		public Boolean getIncludeAssemble() {
+			return includeAssemble;
+		}
+
+		public void setIncludeAssemble(Boolean includeAssemble) {
+			this.includeAssemble = includeAssemble;
+		}
+
+		public Boolean getIncludeCore() {
+			return includeCore;
+		}
+
+		public void setIncludeCore(Boolean includeCore) {
+			this.includeCore = includeCore;
+		}
+
+		public Boolean getIncludeService() {
+			return includeService;
+		}
+
+		public void setIncludeService(Boolean includeService) {
+			this.includeService = includeService;
+		}
+
+		public String getRootPath() {
+			return rootPath;
+		}
+
+		public void setRootPath(String rootPath) {
+			this.rootPath = rootPath;
+		}
+
+		public List<String> getExcludes() {
+			return excludes;
+		}
+
+		public void setExcludes(List<String> excludes) {
+			this.excludes = excludes;
+		}
+
+	}
+}

+ 116 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/CompileM.java

@@ -0,0 +1,116 @@
+package com.x.base.core.project;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.ListTools;
+
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
+
+public class CompileM {
+	public static void main(String[] args) throws Exception {
+		String str = StringUtils.replace(args[0], "\\", "/");
+		Argument arg = XGsonBuilder.instance().fromJson(str, Argument.class);
+		compileAll(arg);
+
+	}
+
+	public static void compileAll(Argument arg) throws Exception {
+		ScanResult scanResult = new FastClasspathScanner(Packages.PREFIX).scan();
+		if (arg.getIncludeCore()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(CoreC.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+		if (arg.getIncludeService()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(ServiceC.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+		if (arg.getIncludeAssemble()) {
+			for (String str : scanResult.getNamesOfSubclassesOf(AssembleC.class)) {
+				Class<?> clz = Class.forName(str);
+				String name = clz.getSimpleName();
+				if (ListTools.nullToEmpty(arg.getExcludes()).contains(name)) {
+					System.out.println("skip name:" + name + ".");
+					continue;
+				}
+				System.out.println("compile name:" + name + ".");
+				Compile.compile(name, arg.getRootPath() + "/" + name);
+			}
+		}
+		// if (arg.includeCenter) {
+		// String name = x_program_center.class.getSimpleName();
+		// System.out.println("compile name:" + name + ".");
+		// Compile.compile(name, arg.getRootPath() + "/" + name);
+		// }
+	}
+
+	public class Argument {
+
+		private String rootPath;
+		private Boolean includeAssemble;
+		private Boolean includeCore;
+		private Boolean includeService;
+
+		private List<String> excludes;
+
+		public Boolean getIncludeAssemble() {
+			return includeAssemble;
+		}
+
+		public void setIncludeAssemble(Boolean includeAssemble) {
+			this.includeAssemble = includeAssemble;
+		}
+
+		public Boolean getIncludeCore() {
+			return includeCore;
+		}
+
+		public void setIncludeCore(Boolean includeCore) {
+			this.includeCore = includeCore;
+		}
+
+		public Boolean getIncludeService() {
+			return includeService;
+		}
+
+		public void setIncludeService(Boolean includeService) {
+			this.includeService = includeService;
+		}
+
+		public String getRootPath() {
+			return rootPath;
+		}
+
+		public void setRootPath(String rootPath) {
+			this.rootPath = rootPath;
+		}
+
+		public List<String> getExcludes() {
+			return excludes;
+		}
+
+		public void setExcludes(List<String> excludes) {
+			this.excludes = excludes;
+		}
+
+	}
+}

+ 29 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Compile_x_base_core_project.java

@@ -0,0 +1,29 @@
+package com.x.base.core.project;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.gson.XGsonBuilder;
+
+public class Compile_x_base_core_project {
+	public static void main(String[] args) throws Exception {
+
+		String str = StringUtils.replace(args[0], "\\", "/");
+		Argument arg = XGsonBuilder.instance().fromJson(str, Argument.class);
+		Compile.compile("x_base_core_project", arg.getRootPath() + "/x_base_core_project");
+
+	}
+
+	public class Argument {
+
+		private String rootPath;
+
+		public String getRootPath() {
+			return rootPath;
+		}
+
+		public void setRootPath(String rootPath) {
+			this.rootPath = rootPath;
+		}
+
+	}
+}

+ 325 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Context.java

@@ -0,0 +1,325 @@
+package com.x.base.core.project;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletRequest;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.openjpa.enhance.PCRegistry;
+import org.quartz.CronScheduleBuilder;
+import org.quartz.DateBuilder;
+import org.quartz.DateBuilder.IntervalUnit;
+import org.quartz.Job;
+import org.quartz.JobBuilder;
+import org.quartz.JobDataMap;
+import org.quartz.JobDetail;
+import org.quartz.Scheduler;
+import org.quartz.SimpleScheduleBuilder;
+import org.quartz.Trigger;
+import org.quartz.TriggerBuilder;
+import org.quartz.impl.StdSchedulerFactory;
+import org.quartz.impl.matchers.EverythingMatcher;
+
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.StorageType;
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.config.DataMappings;
+import com.x.base.core.project.config.StorageMappings;
+import com.x.base.core.project.connection.ActionResponse;
+import com.x.base.core.project.connection.CipherConnectionAction;
+import com.x.base.core.project.jaxrs.WrapClearCacheRequest;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.queue.AbstractQueue;
+import com.x.base.core.project.schedule.JobReportListener;
+import com.x.base.core.project.schedule.ReportToCenter;
+import com.x.base.core.project.schedule.ScheduleLocalRequest;
+import com.x.base.core.project.schedule.ScheduleRequest;
+import com.x.base.core.project.schedule.SchedulerFactoryProperties;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.tools.SslTools;
+import com.x.base.core.project.tools.StringTools;
+
+public class Context extends AbstractContext {
+
+	private static Logger logger = LoggerFactory.getLogger(Context.class);
+
+	/** 从servletContext中抽取context */
+	public static Context fromServletContext(ServletContext servletContext) throws Exception {
+		Object o = servletContext.getAttribute(Context.class.getName());
+		if (null == o) {
+			throw new Exception("can not get context form servletContext.");
+		} else {
+			return (Context) o;
+		}
+	}
+
+	/** 从servletRequest中抽取context */
+	public static Context fromServletRequest(ServletRequest servletRequest) throws Exception {
+		Object o = servletRequest.getServletContext().getAttribute(Context.class.getName());
+		if (null == o) {
+			throw new Exception("can not get context form servletRequest.");
+		} else {
+			return (Context) o;
+		}
+	}
+
+	/* 应用的磁盘路径 */
+	private volatile String path;
+
+	public String path() {
+		return this.path;
+	}
+
+	/* 上下文 */
+	private volatile String servletContextName;
+
+	public String servletContextName() {
+		return this.servletContextName;
+	}
+
+	/* 上下文根 */
+	private volatile ServletContext servletContext;
+
+	public ServletContext servletContext() {
+		return this.servletContext;
+	}
+
+	/* 应用类 */
+	private Class<?> clazz;
+
+	public Class<?> clazz() {
+		return this.clazz;
+	}
+
+	/** 随机令牌 */
+	private volatile String token;
+
+	public String token() {
+		return this.token;
+	}
+
+	/* Storage资源 */
+	private volatile StorageMappings storageMappings;
+
+	public StorageMappings storageMappings() {
+		return this.storageMappings;
+	}
+
+	/* 是否已经初始化完成 */
+	private volatile boolean initialized;
+
+	public boolean initialized() {
+		return this.initialized;
+	}
+
+	/* 应用的权重 */
+	private volatile Integer weight;
+
+	public Integer weight() {
+		return this.weight;
+	}
+
+	private Boolean sslEnable;
+
+	public Boolean sslEnable() {
+		return this.sslEnable;
+	}
+
+	/* quartz 调度器 */
+	public Scheduler scheduler;
+
+	/* 本地任务说明 */
+	private List<ScheduleLocalRequest> scheduleLocalRequestList = new ArrayList<>();
+
+	/* 集群任务说明 */
+	private List<ScheduleRequest> scheduleRequestList = new ArrayList<>();
+
+	private AbstractQueue<WrapClearCacheRequest> clearCacheRequestQueue;
+
+	public AbstractQueue<WrapClearCacheRequest> clearCacheRequestQueue() {
+		return this.clearCacheRequestQueue;
+	}
+
+	/* 队列 */
+	private List<AbstractQueue<?>> queues;
+
+	private Context() throws Exception {
+		this.token = UUID.randomUUID().toString();
+		this.applications = new Applications();
+		this.queues = new ArrayList<AbstractQueue<?>>();
+		this.scheduler = new StdSchedulerFactory(SchedulerFactoryProperties.concrete()).getScheduler();
+		this.scheduler.getListenerManager().addJobListener(new JobReportListener(), EverythingMatcher.allJobs());
+		this.scheduler.start();
+	}
+
+	/** 可以自定义缓存清空消息处理器 */
+	public static Context concrete(ServletContextEvent servletContextEvent,
+			AbstractQueue<WrapClearCacheRequest> clearCacheRequestQueue) throws Exception {
+		Context context = concrete(servletContextEvent);
+		if (null != clearCacheRequestQueue) {
+			context.clearCacheRequestQueue = clearCacheRequestQueue;
+			context.startQueue(clearCacheRequestQueue);
+		}
+		return context;
+	}
+
+	public static Context concrete(ServletContextEvent servletContextEvent) throws Exception {
+		/** 强制忽略ssl服务器认证 */
+		// HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
+		SslTools.ignoreSsl();
+		ServletContext servletContext = servletContextEvent.getServletContext();
+		Context context = new Context();
+		context.path = servletContext.getRealPath("");
+		context.servletContext = servletContext;
+		context.servletContextName = servletContext.getServletContextName();
+		context.clazz = Class.forName(Packages.com_x_base_core_project_dot + context.servletContextName);
+		context.weight = Config.currentNode().getApplication().weight(context.clazz);
+		context.sslEnable = Config.currentNode().getApplication().getSslEnable();
+		context.initDatasFromCenters();
+		context.initStoragesFromCenters();
+		context.scheduleLocal(ReportToCenter.class, 0, ReportToCenter.INTERVAL);
+		context.initialized = true;
+		servletContext.setAttribute(context.getClass().getName(), context);
+		return context;
+	}
+
+	public <T extends Job> void scheduleLocal(Class<T> cls, String cron) throws Exception {
+		JobDataMap jobDataMap = new JobDataMap();
+		jobDataMap.put("context", this);
+		JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(cls.getName(), clazz.getName())
+				.usingJobData(jobDataMap).withDescription(Config.node()).build();
+		Trigger trigger = TriggerBuilder.newTrigger().withIdentity(cls.getName(), clazz.getName())
+				.withDescription("scheduleLocal").withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
+		scheduler.scheduleJob(jobDetail, trigger);
+		this.scheduleLocalRequestList.add(new ScheduleLocalRequest(jobDetail, cron, null, null));
+	}
+
+	public <T extends Job> void scheduleLocal(Class<T> cls, Trigger existTrigger) throws Exception {
+		JobDataMap jobDataMap = new JobDataMap();
+		jobDataMap.put("context", this);
+		JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(cls.getName(), clazz.getName())
+				.usingJobData(jobDataMap).withDescription(Config.node()).build();
+		Trigger trigger = TriggerBuilder.newTrigger().withIdentity(cls.getName(), clazz.getName())
+				.withDescription("scheduleLocal").withSchedule(existTrigger.getScheduleBuilder()).build();
+		scheduler.scheduleJob(jobDetail, trigger);
+		this.scheduleLocalRequestList.add(new ScheduleLocalRequest(jobDetail, null, null, null));
+	}
+
+	public <T extends Job> void scheduleLocal(Class<T> cls, Integer delay, Integer interval) throws Exception {
+		JobDataMap jobDataMap = new JobDataMap();
+		jobDataMap.put("context", this);
+		JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(cls.getName(), clazz.getName())
+				.usingJobData(jobDataMap).withDescription(Config.node()).build();
+		Trigger trigger = TriggerBuilder.newTrigger().withIdentity(cls.getName(), clazz.getName())
+				.withDescription("scheduleLocal").startAt(DateBuilder.futureDate(delay, IntervalUnit.SECOND))
+				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(interval).repeatForever())
+				.build();
+		scheduler.scheduleJob(jobDetail, trigger);
+		this.scheduleLocalRequestList.add(new ScheduleLocalRequest(jobDetail, null, delay, interval));
+	}
+
+	public <T extends Job> void scheduleLocal(Class<T> cls) throws Exception {
+		/* 需要单独生成一个独立任务,保证group和预约的任务不重复 */
+		String group = StringTools.uniqueToken();
+		JobDataMap jobDataMap = new JobDataMap();
+		jobDataMap.put("context", this);
+		JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(cls.getName(), group).usingJobData(jobDataMap)
+				.withDescription(Config.node()).build();
+		/* 经过测试0代表不重复,进运行一次 */
+		Trigger trigger = TriggerBuilder.newTrigger().withIdentity(cls.getName(), group)
+				.withDescription("scheduleLocal")
+				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).withRepeatCount(0))
+				.build();
+		scheduler.scheduleJob(jobDetail, trigger);
+	}
+
+	/* 统一排程任务需要延时90秒,等待instrument启动,每次间隔不能少于5分钟 */
+	public <T extends Job> void schedule(Class<T> clz, String cron) throws Exception {
+		this.scheduleRequestList.add(new ScheduleRequest(clz, this.clazz.getName(), Config.node(), cron));
+	}
+
+	public void startQueue(AbstractQueue<?> queue) {
+		queues.add(queue);
+		queue.start();
+	}
+
+	public void loadApplications() {
+		try {
+			synchronized (this) {
+				ActionResponse response = CipherConnectionAction.get(false,
+						Config.x_program_centerUrlRoot() + "applications");
+				this.applications = response.getData(Applications.class);
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void initDatasFromCenters() throws Exception {
+		@SuppressWarnings("unchecked")
+		List<String> containerEntities = (List<String>) FieldUtils.readStaticField(clazz, "containerEntities");
+		if (ListTools.isNotEmpty(containerEntities)) {
+			logger.print("{} loading datas, entity size:{}.", this.clazz.getName(), containerEntities.size());
+			DataMappings dataMappings = null;
+			do {
+				try {
+					ActionResponse rep = CipherConnectionAction.get(false,
+							Config.x_program_centerUrlRoot() + "datamappings");
+					dataMappings = rep.getData(DataMappings.class);
+				} catch (Exception e) {
+					e.printStackTrace();
+					Thread.sleep(5000);
+				}
+			} while (null == dataMappings);
+			EntityManagerContainerFactory.init(path, dataMappings);
+		}
+	}
+
+	private void initStoragesFromCenters() throws Exception {
+		@SuppressWarnings("unchecked")
+		List<StorageType> usedStorageTypes = (List<StorageType>) FieldUtils.readStaticField(clazz, "usedStorageTypes");
+		if (ListTools.isNotEmpty(usedStorageTypes)) {
+			logger.print("{} loading storages, type size:{}.", this.clazz.getName(), usedStorageTypes.size());
+			StorageMappings storageMappings = null;
+			do {
+				try {
+					ActionResponse rep = CipherConnectionAction.get(false,
+							Config.x_program_centerUrlRoot() + "storagemappings");
+					storageMappings = rep.getData(StorageMappings.class);
+				} catch (Exception e) {
+					e.printStackTrace();
+					Thread.sleep(5000);
+				}
+			} while (null == storageMappings);
+			this.storageMappings = storageMappings;
+		}
+	}
+
+	public void destrory(ServletContextEvent servletContextEvent) {
+		try {
+			queues.stream().forEach(p -> {
+				p.stop();
+			});
+			this.scheduler.shutdown();
+			EntityManagerContainerFactory.close();
+			PCRegistry.deRegister(JpaObject.class.getClassLoader());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	public List<ScheduleLocalRequest> getScheduleLocalRequestList() {
+		return scheduleLocalRequestList;
+	}
+
+	public List<ScheduleRequest> getScheduleRequestList() {
+		return scheduleRequestList;
+	}
+
+}

+ 5 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/CoreA.java

@@ -0,0 +1,5 @@
+package com.x.base.core.project;
+
+public abstract class CoreA extends Compilable {
+
+}

+ 5 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/CoreC.java

@@ -0,0 +1,5 @@
+package com.x.base.core.project;
+
+public abstract class CoreC extends Compilable {
+
+}

+ 5 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/CoreM.java

@@ -0,0 +1,5 @@
+package com.x.base.core.project;
+
+public abstract class CoreM extends Compilable {
+
+}

+ 12 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Deployable.java

@@ -0,0 +1,12 @@
+package com.x.base.core.project;
+
+public abstract class Deployable extends Compilable {
+
+	protected static final String druid_servlet = "<servlet><servlet-name>DruidStatView</servlet-name><servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class></servlet>";
+	protected static final String druid_servlet_mapping = "<servlet-mapping><servlet-name>DruidStatView</servlet-name><url-pattern>/druid/*</url-pattern></servlet-mapping>";
+	protected static final String druid_filter = "<filter><filter-name>DruidWebStatFilter</filter-name><filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class><init-param><param-name>exclusions</param-name><param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value></init-param></filter>";
+	protected static final String druid_filter_mapping = "<filter-mapping><filter-name>DruidWebStatFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>";
+
+	public abstract String pack(String distPath, String repositoryPath) throws Exception;
+
+}

+ 11 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Packages.java

@@ -0,0 +1,11 @@
+package com.x.base.core.project;
+
+public class Packages {
+
+	public static final String PREFIX = "com.x";
+
+	public static final String com_x_base_core_project = "com.x.base.core.project";
+	
+	public static final String com_x_base_core_project_dot = "com.x.base.core.project.";
+
+}

+ 169 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/ServiceA.java

@@ -0,0 +1,169 @@
+package com.x.base.core.project;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.TreeMap;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.JarTools;
+
+public abstract class ServiceA extends Deployable {
+	private File concreteStructure(String distPath, String repositoryPath) throws Exception {
+		File dir = new File(distPath, this.getName());
+		FileUtils.forceMkdir(dir);
+		FileUtils.cleanDirectory(dir);
+		File webInf = new File(dir, "WEB-INF");
+		FileUtils.forceMkdir(webInf);
+		File lib = new File(webInf, "lib");
+		FileUtils.forceMkdir(lib);
+		File classes = new File(webInf, "classes");
+		FileUtils.forceMkdir(classes);
+		File metaInf = new File(classes, "META-INF");
+		FileUtils.forceMkdir(metaInf);
+		this.copyPersistence(metaInf, repositoryPath);
+		this.copyJar_independent(lib, repositoryPath);
+		this.extractJar(classes, repositoryPath);
+		this.extractZip(dir, repositoryPath);
+		this.createWebXml(webInf);
+		return dir;
+	}
+
+	private void createCenterServerFile(File metaInf, String host, Integer port, String cipher) throws Exception {
+		TreeMap<String, Object> map = new TreeMap<>();
+		map.put("host", StringUtils.trimToEmpty(host));
+		map.put("port", null != port ? port : 20080);
+		map.put("cipher", cipher);
+		FileUtils.writeStringToFile(new File(metaInf, "centerServer.json"), XGsonBuilder.toJson(map));
+	}
+
+	private void createConfigFile(File metaInf, String configApplicationServer) throws Exception {
+		TreeMap<String, Object> map = new TreeMap<>();
+		map.put("applicationServer", StringUtils.trimToEmpty(configApplicationServer));
+		FileUtils.writeStringToFile(new File(metaInf, "config.json"), XGsonBuilder.toJson(map));
+	}
+
+	private void copyJar_independent(File lib, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_base_core*.jar"));
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_common_core*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "openjpa"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "ehcache"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "slf4j"), lib, new WildcardFileFilter("*.jar"));
+	}
+
+	private void copyPersistence(File metaInf, String repositoryPath) throws Exception {
+		FileUtils.copyFile(new File(repositoryPath, "x_persistence_" + this.getName() + ".xml"),
+				new File(metaInf, "x_persistence.xml"), false);
+	}
+
+	private void createWebXml(File webInf) throws Exception {
+		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<web-app id=\"" + this.getName()
+				+ "\" metadata-complete=\"false\" version=\"3.0\">" + "<display-name>" + this.getName()
+				+ "</display-name>";
+		xml += druid_servlet;
+		xml += druid_servlet_mapping;
+		xml += druid_filter;
+		xml += druid_filter_mapping;
+		xml += "</web-app>";
+		File file = new File(webInf, "web.xml");
+		FileUtils.writeStringToFile(file, xml, "UTF-8");
+	}
+
+	private void extractJar(File classes, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		Collection<File> files = FileUtils.listFiles(repositoryLib, new WildcardFileFilter(this.getName() + "*.jar"),
+				null);
+		JarTools.unjar(files.iterator().next(), "", classes, true);
+	}
+
+	private void extractZip(File dir, String repositoryPath) throws Exception {
+		File file = new File(repositoryPath, this.getName() + ".zip");
+		JarTools.unjar(file, "", dir, true);
+	}
+
+	@Override
+	public String pack(String distPath, String repositoryPath) throws Exception {
+		File dir = this.concreteStructure(distPath, repositoryPath);
+		custom(dir, repositoryPath);
+		File war = new File(distPath, this.getName() + ".war");
+		JarTools.jar(dir, war);
+		return war.getAbsolutePath();
+	}
+
+	protected abstract void custom(File dir, String repositoryPath) throws Exception;
+
+	protected String getName() {
+		return StringUtils.replace(this.getClass().getSimpleName(), ".", "_");
+	}
+
+	public class Argument {
+		private String distPath;
+		private String repositoryPath;
+		private String resourcesPath;
+		private String centerHost;
+		private Integer centerPort;
+		private String centerCipher;
+		private String configApplicationServer;
+
+		public String getDistPath() {
+			return distPath;
+		}
+
+		public void setDistPath(String distPath) {
+			this.distPath = distPath;
+		}
+
+		public String getRepositoryPath() {
+			return repositoryPath;
+		}
+
+		public void setRepositoryPath(String repositoryPath) {
+			this.repositoryPath = repositoryPath;
+		}
+
+		public String getResourcesPath() {
+			return resourcesPath;
+		}
+
+		public void setResourcesPath(String resourcesPath) {
+			this.resourcesPath = resourcesPath;
+		}
+
+		public String getCenterHost() {
+			return centerHost;
+		}
+
+		public void setCenterHost(String centerHost) {
+			this.centerHost = centerHost;
+		}
+
+		public Integer getCenterPort() {
+			return centerPort;
+		}
+
+		public void setCenterPort(Integer centerPort) {
+			this.centerPort = centerPort;
+		}
+
+		public String getCenterCipher() {
+			return centerCipher;
+		}
+
+		public void setCenterCipher(String centerCipher) {
+			this.centerCipher = centerCipher;
+		}
+
+		public String getConfigApplicationServer() {
+			return configApplicationServer;
+		}
+
+		public void setConfigApplicationServer(String configApplicationServer) {
+			this.configApplicationServer = configApplicationServer;
+		}
+
+	}
+}

+ 169 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/ServiceC.java

@@ -0,0 +1,169 @@
+package com.x.base.core.project;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.TreeMap;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.JarTools;
+
+public abstract class ServiceC extends Deployable {
+	private File concreteStructure(String distPath, String repositoryPath) throws Exception {
+		File dir = new File(distPath, this.getName());
+		FileUtils.forceMkdir(dir);
+		FileUtils.cleanDirectory(dir);
+		File webInf = new File(dir, "WEB-INF");
+		FileUtils.forceMkdir(webInf);
+		File lib = new File(webInf, "lib");
+		FileUtils.forceMkdir(lib);
+		File classes = new File(webInf, "classes");
+		FileUtils.forceMkdir(classes);
+		File metaInf = new File(classes, "META-INF");
+		FileUtils.forceMkdir(metaInf);
+		this.copyPersistence(metaInf, repositoryPath);
+		this.copyJar_independent(lib, repositoryPath);
+		this.extractJar(classes, repositoryPath);
+		this.extractZip(dir, repositoryPath);
+		this.createWebXml(webInf);
+		return dir;
+	}
+
+	private void createCenterServerFile(File metaInf, String host, Integer port, String cipher) throws Exception {
+		TreeMap<String, Object> map = new TreeMap<>();
+		map.put("host", StringUtils.trimToEmpty(host));
+		map.put("port", null != port ? port : 20080);
+		map.put("cipher", cipher);
+		FileUtils.writeStringToFile(new File(metaInf, "centerServer.json"), XGsonBuilder.toJson(map));
+	}
+
+	private void createConfigFile(File metaInf, String configApplicationServer) throws Exception {
+		TreeMap<String, Object> map = new TreeMap<>();
+		map.put("applicationServer", StringUtils.trimToEmpty(configApplicationServer));
+		FileUtils.writeStringToFile(new File(metaInf, "config.json"), XGsonBuilder.toJson(map));
+	}
+
+	private void copyJar_independent(File lib, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_base_core*.jar"));
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_common_core*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "openjpa"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "ehcache"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "slf4j"), lib, new WildcardFileFilter("*.jar"));
+	}
+
+	private void copyPersistence(File metaInf, String repositoryPath) throws Exception {
+		FileUtils.copyFile(new File(repositoryPath, "x_persistence_" + this.getName() + ".xml"),
+				new File(metaInf, "x_persistence.xml"), false);
+	}
+
+	private void createWebXml(File webInf) throws Exception {
+		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<web-app id=\"" + this.getName()
+				+ "\" metadata-complete=\"false\" version=\"3.0\">" + "<display-name>" + this.getName()
+				+ "</display-name>";
+		xml += druid_servlet;
+		xml += druid_servlet_mapping;
+		xml += druid_filter;
+		xml += druid_filter_mapping;
+		xml += "</web-app>";
+		File file = new File(webInf, "web.xml");
+		FileUtils.writeStringToFile(file, xml, "UTF-8");
+	}
+
+	private void extractJar(File classes, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		Collection<File> files = FileUtils.listFiles(repositoryLib, new WildcardFileFilter(this.getName() + "*.jar"),
+				null);
+		JarTools.unjar(files.iterator().next(), "", classes, true);
+	}
+
+	private void extractZip(File dir, String repositoryPath) throws Exception {
+		File file = new File(repositoryPath, this.getName() + ".zip");
+		JarTools.unjar(file, "", dir, true);
+	}
+
+	@Override
+	public String pack(String distPath, String repositoryPath) throws Exception {
+		File dir = this.concreteStructure(distPath, repositoryPath);
+		custom(dir, repositoryPath);
+		File war = new File(distPath, this.getName() + ".war");
+		JarTools.jar(dir, war);
+		return war.getAbsolutePath();
+	}
+
+	protected abstract void custom(File dir, String repositoryPath) throws Exception;
+
+	protected String getName() {
+		return StringUtils.replace(this.getClass().getSimpleName(), ".", "_");
+	}
+
+	public class Argument {
+		private String distPath;
+		private String repositoryPath;
+		private String resourcesPath;
+		private String centerHost;
+		private Integer centerPort;
+		private String centerCipher;
+		private String configApplicationServer;
+
+		public String getDistPath() {
+			return distPath;
+		}
+
+		public void setDistPath(String distPath) {
+			this.distPath = distPath;
+		}
+
+		public String getRepositoryPath() {
+			return repositoryPath;
+		}
+
+		public void setRepositoryPath(String repositoryPath) {
+			this.repositoryPath = repositoryPath;
+		}
+
+		public String getResourcesPath() {
+			return resourcesPath;
+		}
+
+		public void setResourcesPath(String resourcesPath) {
+			this.resourcesPath = resourcesPath;
+		}
+
+		public String getCenterHost() {
+			return centerHost;
+		}
+
+		public void setCenterHost(String centerHost) {
+			this.centerHost = centerHost;
+		}
+
+		public Integer getCenterPort() {
+			return centerPort;
+		}
+
+		public void setCenterPort(Integer centerPort) {
+			this.centerPort = centerPort;
+		}
+
+		public String getCenterCipher() {
+			return centerCipher;
+		}
+
+		public void setCenterCipher(String centerCipher) {
+			this.centerCipher = centerCipher;
+		}
+
+		public String getConfigApplicationServer() {
+			return configApplicationServer;
+		}
+
+		public void setConfigApplicationServer(String configApplicationServer) {
+			this.configApplicationServer = configApplicationServer;
+		}
+
+	}
+}

+ 169 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/ServiceM.java

@@ -0,0 +1,169 @@
+package com.x.base.core.project;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.TreeMap;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.JarTools;
+
+public abstract class ServiceM extends Deployable {
+	private File concreteStructure(String distPath, String repositoryPath) throws Exception {
+		File dir = new File(distPath, this.getName());
+		FileUtils.forceMkdir(dir);
+		FileUtils.cleanDirectory(dir);
+		File webInf = new File(dir, "WEB-INF");
+		FileUtils.forceMkdir(webInf);
+		File lib = new File(webInf, "lib");
+		FileUtils.forceMkdir(lib);
+		File classes = new File(webInf, "classes");
+		FileUtils.forceMkdir(classes);
+		File metaInf = new File(classes, "META-INF");
+		FileUtils.forceMkdir(metaInf);
+		this.copyPersistence(metaInf, repositoryPath);
+		this.copyJar_independent(lib, repositoryPath);
+		this.extractJar(classes, repositoryPath);
+		this.extractZip(dir, repositoryPath);
+		this.createWebXml(webInf);
+		return dir;
+	}
+
+	private void createCenterServerFile(File metaInf, String host, Integer port, String cipher) throws Exception {
+		TreeMap<String, Object> map = new TreeMap<>();
+		map.put("host", StringUtils.trimToEmpty(host));
+		map.put("port", null != port ? port : 20080);
+		map.put("cipher", cipher);
+		FileUtils.writeStringToFile(new File(metaInf, "centerServer.json"), XGsonBuilder.toJson(map));
+	}
+
+	private void createConfigFile(File metaInf, String configApplicationServer) throws Exception {
+		TreeMap<String, Object> map = new TreeMap<>();
+		map.put("applicationServer", StringUtils.trimToEmpty(configApplicationServer));
+		FileUtils.writeStringToFile(new File(metaInf, "config.json"), XGsonBuilder.toJson(map));
+	}
+
+	private void copyJar_independent(File lib, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_base_core*.jar"));
+		FileUtils.copyDirectory(repositoryLib, lib, new WildcardFileFilter("x_common_core*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "openjpa"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "ehcache"), lib, new WildcardFileFilter("*.jar"));
+		FileUtils.copyDirectory(new File(repositoryLib, "slf4j"), lib, new WildcardFileFilter("*.jar"));
+	}
+
+	private void copyPersistence(File metaInf, String repositoryPath) throws Exception {
+		FileUtils.copyFile(new File(repositoryPath, "x_persistence_" + this.getName() + ".xml"),
+				new File(metaInf, "x_persistence.xml"), false);
+	}
+
+	private void createWebXml(File webInf) throws Exception {
+		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<web-app id=\"" + this.getName()
+				+ "\" metadata-complete=\"false\" version=\"3.0\">" + "<display-name>" + this.getName()
+				+ "</display-name>";
+		xml += druid_servlet;
+		xml += druid_servlet_mapping;
+		xml += druid_filter;
+		xml += druid_filter_mapping;
+		xml += "</web-app>";
+		File file = new File(webInf, "web.xml");
+		FileUtils.writeStringToFile(file, xml, "UTF-8");
+	}
+
+	private void extractJar(File classes, String repositoryPath) throws Exception {
+		File repositoryLib = new File(repositoryPath);
+		Collection<File> files = FileUtils.listFiles(repositoryLib, new WildcardFileFilter(this.getName() + "*.jar"),
+				null);
+		JarTools.unjar(files.iterator().next(), "", classes, true);
+	}
+
+	private void extractZip(File dir, String repositoryPath) throws Exception {
+		File file = new File(repositoryPath, this.getName() + ".zip");
+		JarTools.unjar(file, "", dir, true);
+	}
+
+	@Override
+	public String pack(String distPath, String repositoryPath) throws Exception {
+		File dir = this.concreteStructure(distPath, repositoryPath);
+		custom(dir, repositoryPath);
+		File war = new File(distPath, this.getName() + ".war");
+		JarTools.jar(dir, war);
+		return war.getAbsolutePath();
+	}
+
+	protected abstract void custom(File dir, String repositoryPath) throws Exception;
+
+	protected String getName() {
+		return StringUtils.replace(this.getClass().getSimpleName(), ".", "_");
+	}
+
+	public class Argument {
+		private String distPath;
+		private String repositoryPath;
+		private String resourcesPath;
+		private String centerHost;
+		private Integer centerPort;
+		private String centerCipher;
+		private String configApplicationServer;
+
+		public String getDistPath() {
+			return distPath;
+		}
+
+		public void setDistPath(String distPath) {
+			this.distPath = distPath;
+		}
+
+		public String getRepositoryPath() {
+			return repositoryPath;
+		}
+
+		public void setRepositoryPath(String repositoryPath) {
+			this.repositoryPath = repositoryPath;
+		}
+
+		public String getResourcesPath() {
+			return resourcesPath;
+		}
+
+		public void setResourcesPath(String resourcesPath) {
+			this.resourcesPath = resourcesPath;
+		}
+
+		public String getCenterHost() {
+			return centerHost;
+		}
+
+		public void setCenterHost(String centerHost) {
+			this.centerHost = centerHost;
+		}
+
+		public Integer getCenterPort() {
+			return centerPort;
+		}
+
+		public void setCenterPort(Integer centerPort) {
+			this.centerPort = centerPort;
+		}
+
+		public String getCenterCipher() {
+			return centerCipher;
+		}
+
+		public void setCenterCipher(String centerCipher) {
+			this.centerCipher = centerCipher;
+		}
+
+		public String getConfigApplicationServer() {
+			return configApplicationServer;
+		}
+
+		public void setConfigApplicationServer(String configApplicationServer) {
+			this.configApplicationServer = configApplicationServer;
+		}
+
+	}
+}

+ 736 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/Describe.java

@@ -0,0 +1,736 @@
+package com.x.base.core.project.annotation;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.commons.collections4.list.SetUniqueList;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.commons.lang3.reflect.MethodUtils;
+import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
+import org.glassfish.jersey.media.multipart.FormDataParam;
+import org.junit.Test;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.base.core.project.tools.DefaultCharset;
+import com.x.base.core.project.tools.ListTools;
+
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
+
+public class Describe {
+
+	public static void main(String[] args) {
+		Describe describe = new Describe();
+		describe.scan(args[0], args[1]);
+	}
+
+	private void scan(String directory, String name) {
+		try {
+			List<JaxrsClass> jaxrsClasses = new ArrayList<>();
+			List<Class<?>> classes = this.scanJaxrsClass(name);
+			for (Class<?> clz : classes) {
+				if (StandardJaxrsAction.class.isAssignableFrom(clz)) {
+					jaxrsClasses.add(this.jaxrsClass(clz));
+				}
+			}
+			LinkedHashMap<String, List<?>> map = new LinkedHashMap<>();
+			jaxrsClasses = jaxrsClasses.stream().sorted(Comparator.comparing(JaxrsClass::getName))
+					.collect(Collectors.toList());
+			map.put("jaxrs", jaxrsClasses);
+			File dir = new File(directory);
+			FileUtils.forceMkdir(dir);
+			File file = new File(dir, "describe.json");
+			FileUtils.writeStringToFile(file, XGsonBuilder.toJson(map), DefaultCharset.charset);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	private List<Class<?>> scanJaxrsClass(String name) throws Exception {
+		// String pack = "com." + name.replaceAll("_", ".");
+		String pack = "";
+		if (StringUtils.startsWith(name, "o2_")) {
+			pack = name.replaceAll("_", ".");
+		} else {
+			pack = "com." + name.replaceAll("_", ".");
+		}
+		ScanResult scanResult = new FastClasspathScanner(pack).scan();
+		SetUniqueList<Class<?>> classes = SetUniqueList.setUniqueList(new ArrayList<Class<?>>());
+		for (String str : scanResult.getNamesOfClassesWithAnnotationsAllOf(ApplicationPath.class)) {
+			Class<?> applicationPathClass = ClassUtils.getClass(str);
+			for (Class<?> o : (Set<Class<?>>) MethodUtils.invokeMethod(applicationPathClass.newInstance(),
+					"getClasses")) {
+				Path path = o.getAnnotation(Path.class);
+				JaxrsDescribe jaxrsDescribe = o.getAnnotation(JaxrsDescribe.class);
+				if (null != path && null != jaxrsDescribe) {
+					classes.add(o);
+				}
+			}
+		}
+		return classes;
+	}
+
+	private JaxrsClass jaxrsClass(Class<?> clz) throws Exception {
+		System.out.println("describe class:" + clz.getName());
+		JaxrsDescribe jaxrsDescribe = clz.getAnnotation(JaxrsDescribe.class);
+		JaxrsClass jaxrsClass = new JaxrsClass();
+		jaxrsClass.setClassName(clz.getName());
+		jaxrsClass.setName(clz.getSimpleName());
+		jaxrsClass.setDescription(jaxrsDescribe.value());
+		for (Method method : clz.getMethods()) {
+			JaxrsMethodDescribe jaxrsMethodDescribe = method.getAnnotation(JaxrsMethodDescribe.class);
+			if (null != jaxrsMethodDescribe) {
+				jaxrsClass.getMethods().add(this.jaxrsMethod(clz, method));
+			}
+		}
+		jaxrsClass.setMethods(jaxrsClass.getMethods().stream().sorted(Comparator.comparing(JaxrsMethod::getName))
+				.collect(Collectors.toList()));
+		return jaxrsClass;
+	}
+
+	private JaxrsMethod jaxrsMethod(Class<?> clz, Method method) throws Exception {
+		JaxrsMethodDescribe jaxrsMethodDescribe = method.getAnnotation(JaxrsMethodDescribe.class);
+		JaxrsMethod jaxrsMethod = new JaxrsMethod();
+		jaxrsMethod.setName(method.getName());
+		jaxrsMethod.setDescription(jaxrsMethodDescribe.value());
+		Class<?> actionClass = jaxrsMethodDescribe.action();
+		jaxrsMethod.setClassName(actionClass.getName());
+		if (null != method.getAnnotation(GET.class)) {
+			jaxrsMethod.setType("GET");
+		} else if (null != method.getAnnotation(POST.class)) {
+			jaxrsMethod.setType("POST");
+		} else if (null != method.getAnnotation(PUT.class)) {
+			jaxrsMethod.setType("PUT");
+		} else if (null != method.getAnnotation(DELETE.class)) {
+			jaxrsMethod.setType("DELETE");
+		} else if (null != method.getAnnotation(OPTIONS.class)) {
+			jaxrsMethod.setType("OPTIONS");
+		} else if (null != method.getAnnotation(HEAD.class)) {
+			jaxrsMethod.setType("HEAD");
+		}
+		Class<?> woClass = this.getWoClass(actionClass);
+		if (null != woClass) {
+			jaxrsMethod.setOuts(this.jaxrsOutField(woClass));
+		}
+		Class<?> wiClass = this.getWiClass(actionClass);
+		if (null != wiClass) {
+			jaxrsMethod.setIns(this.jaxrsInField(wiClass));
+		} else {
+			/** 如果没有定义Wi对象,那么有可能使用的是jsonElement对象 */
+			if (ArrayUtils.contains(method.getParameterTypes(), JsonElement.class)) {
+				jaxrsMethod.setUseJsonElementParameter(true);
+			}
+		}
+		Consumes consumes = method.getAnnotation(Consumes.class);
+		if (null != consumes) {
+			jaxrsMethod.setContentType(consumes.value()[0]);
+		} else {
+			jaxrsMethod.setContentType(MediaType.APPLICATION_JSON);
+		}
+		Produces produces = method.getAnnotation(Produces.class);
+		if (null != produces) {
+			jaxrsMethod.setResultContentType(produces.value()[0]);
+			jaxrsMethod.setResultContentType(produces.value()[0]);
+		}
+		Path path = method.getAnnotation(Path.class);
+		if (null == path) {
+			jaxrsMethod.setPath("jaxrs/" + clz.getAnnotation(Path.class).value());
+		} else {
+			jaxrsMethod.setPath("jaxrs/" + clz.getAnnotation(Path.class).value() + "/" + path.value());
+		}
+		for (Parameter o : method.getParameters()) {
+			FormDataParam formDataParam = o.getAnnotation(FormDataParam.class);
+			FormParam formParam = o.getAnnotation(FormParam.class);
+			PathParam pathParam = o.getAnnotation(PathParam.class);
+			QueryParam queryParam = o.getAnnotation(QueryParam.class);
+			if (null != formDataParam) {
+				jaxrsMethod.getFormParameters().add(this.jaxrsFormDataParameter(o));
+			} else if (null != formParam) {
+				jaxrsMethod.getFormParameters().add(this.jaxrsFormParameter(o));
+			} else if (null != queryParam) {
+				jaxrsMethod.getQueryParameters().add(this.jaxrsQueryParameter(o));
+			} else if (null != pathParam) {
+				jaxrsMethod.getPathParameters().add(this.jaxrsPathParameter(o));
+			}
+		}
+		jaxrsMethod.setFormParameters(jaxrsMethod.getFormParameters().stream().filter(Objects::nonNull)
+				.sorted(Comparator.comparing(JaxrsFormParameter::getName, Comparator.nullsLast(String::compareTo)))
+				.collect(Collectors.toList()));
+		jaxrsMethod.setQueryParameters(jaxrsMethod.getQueryParameters().stream().filter(Objects::nonNull)
+				.sorted(Comparator.comparing(JaxrsQueryParameter::getName, Comparator.nullsLast(String::compareTo)))
+				.collect(Collectors.toList()));
+		jaxrsMethod.setPathParameters(jaxrsMethod.getPathParameters().stream().filter(Objects::nonNull)
+				.sorted(Comparator.comparing(JaxrsPathParameter::getName, Comparator.nullsLast(String::compareTo)))
+				.collect(Collectors.toList()));
+		return jaxrsMethod;
+	}
+
+	private JaxrsFormParameter jaxrsFormDataParameter(Parameter parameter) {
+		JaxrsParameterDescribe jaxrsParameterDescribe = parameter.getAnnotation(JaxrsParameterDescribe.class);
+		FormDataParam formDataParam = parameter.getAnnotation(FormDataParam.class);
+		if (StringUtils.equalsIgnoreCase("file", formDataParam.value())) {
+			if (parameter.getType() == FormDataContentDisposition.class) {
+				/** 单独处理附件 */
+				JaxrsFormParameter o = new JaxrsFormParameter();
+				o.setType("File");
+				o.setName(formDataParam.value());
+				if (null != jaxrsParameterDescribe) {
+					o.setDescription(jaxrsParameterDescribe.value());
+				} else {
+					System.err.println("[" + formDataParam.value() + "], 未设置JaxrsParameterDescribe");
+					o.setDescription("");
+				}
+				return o;
+			}
+		} else {
+			JaxrsFormParameter o = new JaxrsFormParameter();
+			o.setType(this.simpleType(parameter.getType().toString()));
+			o.setName(formDataParam.value());
+			if (null != jaxrsParameterDescribe) {
+				o.setDescription(jaxrsParameterDescribe.value());
+			} else {
+				System.err.println("[" + formDataParam.value() + "], 未设置JaxrsParameterDescribe");
+				o.setDescription("");
+			}
+			return o;
+		}
+		return null;
+	}
+
+	private JaxrsFormParameter jaxrsFormParameter(Parameter parameter) {
+		JaxrsParameterDescribe jaxrsParameterDescribe = parameter.getAnnotation(JaxrsParameterDescribe.class);
+		FormParam formParam = parameter.getAnnotation(FormParam.class);
+		JaxrsFormParameter o = new JaxrsFormParameter();
+		o.setType(this.simpleType(parameter.getType().toString()));
+		o.setName(formParam.value());
+		if (null != jaxrsParameterDescribe) {
+			o.setDescription(jaxrsParameterDescribe.value());
+		} else {
+			System.err.println("[" + formParam.value() + "], 未设置JaxrsParameterDescribe");
+			o.setDescription("");
+		}
+		return o;
+	}
+
+	private JaxrsQueryParameter jaxrsQueryParameter(Parameter parameter) {
+		JaxrsParameterDescribe jaxrsParameterDescribe = parameter.getAnnotation(JaxrsParameterDescribe.class);
+		QueryParam queryParam = parameter.getAnnotation(QueryParam.class);
+		JaxrsQueryParameter o = new JaxrsQueryParameter();
+		if (null != jaxrsParameterDescribe) {
+			o.setDescription(jaxrsParameterDescribe.value());
+		} else {
+			System.err.println("[" + queryParam.value() + "], 未设置JaxrsParameterDescribe");
+			o.setDescription("");
+		}
+		o.setName(queryParam.value());
+		o.setType(this.simpleType(parameter.getType().getName()));
+		return o;
+	}
+
+	private JaxrsPathParameter jaxrsPathParameter(Parameter parameter) throws Exception {
+		JaxrsParameterDescribe jaxrsParameterDescribe = parameter.getAnnotation(JaxrsParameterDescribe.class);
+		PathParam pathParam = parameter.getAnnotation(PathParam.class);
+		JaxrsPathParameter o = new JaxrsPathParameter();
+		o.setName(pathParam.value());
+		if (null != jaxrsParameterDescribe) {
+			o.setDescription(jaxrsParameterDescribe.value());
+		} else {
+			System.err.println("[" + pathParam.value() + "], 未设置JaxrsParameterDescribe");
+			o.setDescription("");
+		}
+		o.setType(this.getJaxrsParameterType(parameter));
+		return o;
+	}
+
+	private Class<?> getWiClass(Class<?> actionClass) {
+		for (Class<?> c : actionClass.getDeclaredClasses()) {
+			if (StringUtils.equals(c.getSimpleName(), "Wi")) {
+				return c;
+			}
+		}
+		return null;
+	}
+
+	private Class<?> getWoClass(Class<?> actionClass) {
+		for (Class<?> c : actionClass.getDeclaredClasses()) {
+			if (StringUtils.equals(c.getSimpleName(), "Wo")) {
+				return c;
+			}
+		}
+		return null;
+	}
+
+	private List<JaxrsField> jaxrsInField(Class<?> clz) throws Exception {
+		List<JaxrsField> list = new ArrayList<>();
+		List<Field> fields = FieldUtils.getAllFieldsList(clz);
+		List<String> copierCopyFields = this.listCopierCopyFields(clz);
+		if (ListTools.isNotEmpty(copierCopyFields)) {
+			List<Field> os = new ArrayList<>();
+			for (Field o : fields) {
+				FieldDescribe fieldDescribe = o.getAnnotation(FieldDescribe.class);
+				if ((null != fieldDescribe)
+						&& (copierCopyFields.contains(o.getName()) || this.inWiNotInEntity(o.getName(), clz))) {
+					os.add(o);
+				}
+				fields = os;
+			}
+		}
+		for (Field o : fields) {
+			FieldDescribe fieldDescribe = o.getAnnotation(FieldDescribe.class);
+			if (null != fieldDescribe) {
+				JaxrsField jaxrsField = new JaxrsField();
+				jaxrsField.setName(o.getName());
+				jaxrsField.setDescription(fieldDescribe.value());
+				jaxrsField.setType(this.getJaxrsFieldType(o));
+				jaxrsField.setIsBaseType(false);
+				if (Collection.class.isAssignableFrom(o.getType())) {
+					jaxrsField.setIsCollection(true);
+					if (StringUtils.containsAny(jaxrsField.getType(), "<String>", "<Boolean>", "<Date>", "<Integer>",
+							"<Double>", "<Long>", "<Float>")) {
+						jaxrsField.setIsBaseType(true);
+					}
+				} else {
+					jaxrsField.setIsCollection(false);
+					if (StringUtils.startsWithAny(jaxrsField.getType(), "String", "Boolean", "Date", "Integer",
+							"Double", "Long", "Float")) {
+						jaxrsField.setIsBaseType(true);
+					}
+				}
+				list.add(jaxrsField);
+			}
+		}
+		return list;
+	}
+
+	private List<JaxrsField> jaxrsOutField(Class<?> clz) throws Exception {
+		List<JaxrsField> list = new ArrayList<>();
+		List<Field> fields = FieldUtils.getAllFieldsList(clz);
+		List<String> copierEraseFields = this.listCopierEraseFields(clz);
+		if (ListTools.isNotEmpty(copierEraseFields)) {
+			List<Field> os = new ArrayList<>();
+			for (Field o : fields) {
+				FieldDescribe fieldDescribe = o.getAnnotation(FieldDescribe.class);
+				if ((null != fieldDescribe) && (!copierEraseFields.contains(o.getName()))) {
+					os.add(o);
+				}
+			}
+			fields = os;
+		}
+		for (Field o : fields) {
+			FieldDescribe fieldDescribe = o.getAnnotation(FieldDescribe.class);
+			if (null != fieldDescribe) {
+				JaxrsField jaxrsField = new JaxrsField();
+				jaxrsField.setName(o.getName());
+				jaxrsField.setDescription(fieldDescribe.value());
+				jaxrsField.setType(this.getJaxrsFieldType(o));
+				if (Collection.class.isAssignableFrom(o.getType())) {
+					jaxrsField.setIsCollection(true);
+				} else {
+					jaxrsField.setIsCollection(false);
+				}
+				list.add(jaxrsField);
+			}
+		}
+		return list;
+	}
+
+	private String getJaxrsFieldType(Field o) {
+		String value = o.getGenericType().getTypeName();
+		return this.simpleType(value);
+	}
+
+	private String getJaxrsParameterType(Parameter o) {
+		String value = o.getType().getTypeName();
+		return this.simpleType(value);
+	}
+
+	private String simpleType(String value) {
+		value = value.replaceAll(" ", "");
+		String[] ss = value.split("[,|<|>]");
+		for (String s : ss) {
+			String[] ns = s.split("[.|\\$]");
+			value = value.replace(s, ns[ns.length - 1]);
+		}
+		return value;
+	}
+
+	private List<String> listCopierEraseFields(Class<?> clz) {
+		try {
+			Object o = FieldUtils.readStaticField(clz, "copier", true);
+			WrapCopier copier = (WrapCopier) o;
+			return copier.getEraseFields();
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	private List<String> listCopierCopyFields(Class<?> clz) {
+		try {
+			Object o = FieldUtils.readStaticField(clz, "copier", true);
+			WrapCopier copier = (WrapCopier) o;
+			return copier.getCopyFields();
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	/** 判断字段是否在Wi中但是没有在Entity类中说明是Wi新增字段,需要进行描述 */
+	private Boolean inWiNotInEntity(String field, Class<?> clz) {
+		try {
+			Object o = FieldUtils.readStaticField(clz, "copier", true);
+			WrapCopier copier = (WrapCopier) o;
+			if ((null != FieldUtils.getField(copier.getOrigClass(), field, true))
+					&& (null == FieldUtils.getField(copier.getDestClass(), field, true))) {
+				return true;
+			}
+			return false;
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	public class JaxrsClass {
+
+		private String name;
+		private String className;
+		private String description;
+		private List<JaxrsMethod> methods = new ArrayList<>();
+
+		public String getClassName() {
+			return className;
+		}
+
+		public void setClassName(String className) {
+			this.className = className;
+		}
+
+		public List<JaxrsMethod> getMethods() {
+			return methods;
+		}
+
+		public void setMethods(List<JaxrsMethod> methods) {
+			this.methods = methods;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public void setDescription(String description) {
+			this.description = description;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+	}
+
+	public class JaxrsMethod {
+		private String name;
+		private String className;
+		private String description;
+		private String type;
+		private String path;
+		private String contentType;
+		private String resultContentType;
+		private Boolean useJsonElementParameter = false;
+		private List<JaxrsPathParameter> pathParameters = new ArrayList<>();
+		private List<JaxrsFormParameter> formParameters = new ArrayList<>();
+		private List<JaxrsQueryParameter> queryParameters = new ArrayList<>();
+		private List<JaxrsField> ins = new ArrayList<>();
+		private List<JaxrsField> outs = new ArrayList<>();
+
+		public String getType() {
+			return type;
+		}
+
+		public void setType(String type) {
+			this.type = type;
+		}
+
+		public String getPath() {
+			return path;
+		}
+
+		public void setPath(String path) {
+			this.path = path;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public List<JaxrsField> getIns() {
+			return ins;
+		}
+
+		public void setIns(List<JaxrsField> ins) {
+			this.ins = ins;
+		}
+
+		public List<JaxrsField> getOuts() {
+			return outs;
+		}
+
+		public void setOuts(List<JaxrsField> outs) {
+			this.outs = outs;
+		}
+
+		public String getContentType() {
+			return contentType;
+		}
+
+		public void setContentType(String contentType) {
+			this.contentType = contentType;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public void setDescription(String description) {
+			this.description = description;
+		}
+
+		public String getClassName() {
+			return className;
+		}
+
+		public void setClassName(String className) {
+			this.className = className;
+		}
+
+		public List<JaxrsPathParameter> getPathParameters() {
+			return pathParameters;
+		}
+
+		public void setPathParameters(List<JaxrsPathParameter> pathParameters) {
+			this.pathParameters = pathParameters;
+		}
+
+		public List<JaxrsFormParameter> getFormParameters() {
+			return formParameters;
+		}
+
+		public void setFormParameters(List<JaxrsFormParameter> formParameters) {
+			this.formParameters = formParameters;
+		}
+
+		public List<JaxrsQueryParameter> getQueryParameters() {
+			return queryParameters;
+		}
+
+		public void setQueryParameters(List<JaxrsQueryParameter> queryParameters) {
+			this.queryParameters = queryParameters;
+		}
+
+		public Boolean getUseJsonElementParameter() {
+			return useJsonElementParameter;
+		}
+
+		public void setUseJsonElementParameter(Boolean useJsonElementParameter) {
+			this.useJsonElementParameter = useJsonElementParameter;
+		}
+
+		public String getResultContentType() {
+			return resultContentType;
+		}
+
+		public void setResultContentType(String resultContentType) {
+			this.resultContentType = resultContentType;
+		}
+
+	}
+
+	public class JaxrsField {
+
+		private String name;
+		private String type;
+		private Boolean isCollection;
+		private String description;
+		private Boolean isBaseType;
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public void setDescription(String description) {
+			this.description = description;
+		}
+
+		public String getType() {
+			return type;
+		}
+
+		public void setType(String type) {
+			this.type = type;
+		}
+
+		public Boolean getIsCollection() {
+			return isCollection;
+		}
+
+		public void setIsCollection(Boolean isCollection) {
+			this.isCollection = isCollection;
+		}
+
+		public Boolean getIsBaseType() {
+			return isBaseType;
+		}
+
+		public void setIsBaseType(Boolean isBaseType) {
+			this.isBaseType = isBaseType;
+		}
+
+	}
+
+	public class JaxrsPathParameter {
+
+		private String name;
+		private String type;
+		private String description;
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public void setDescription(String description) {
+			this.description = description;
+		}
+
+		public String getType() {
+			return type;
+		}
+
+		public void setType(String type) {
+			this.type = type;
+		}
+
+	}
+
+	public class JaxrsFormParameter {
+
+		private String name;
+		private String type;
+		private String description;
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public void setDescription(String description) {
+			this.description = description;
+		}
+
+		public String getType() {
+			return type;
+		}
+
+		public void setType(String type) {
+			this.type = type;
+		}
+
+	}
+
+	public class JaxrsQueryParameter {
+
+		private String name;
+		private String type;
+		private String description;
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public void setDescription(String description) {
+			this.description = description;
+		}
+
+		public String getType() {
+			return type;
+		}
+
+		public void setType(String type) {
+			this.type = type;
+		}
+
+	}
+
+	@Test
+	public void test1() {
+		Describe o = new Describe();
+		o.scan("d:/x/x_processplatform_assemble_surface/describe", "x_processplatform_assemble_surface");
+	}
+}

+ 18 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/FieldDescribe.java

@@ -0,0 +1,18 @@
+package com.x.base.core.project.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+//@java.lang.annotation.Target(value={java.lang.annotation.ElementType.PARAMETER,java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.FIELD})
+//@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.RUNTIME)
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@Inherited
+public @interface FieldDescribe {
+	abstract String value();
+}

+ 14 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/JaxrsDescribe.java

@@ -0,0 +1,14 @@
+package com.x.base.core.project.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+public @interface JaxrsDescribe {
+	String value();
+}

+ 22 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/JaxrsMethodDescribe.java

@@ -0,0 +1,22 @@
+package com.x.base.core.project.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+@Inherited
+@Documented
+public @interface JaxrsMethodDescribe {
+
+	String value();
+
+	Class<? extends StandardJaxrsAction> action();
+
+}

+ 18 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/annotation/JaxrsParameterDescribe.java

@@ -0,0 +1,18 @@
+package com.x.base.core.project.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+//@java.lang.annotation.Target(value={java.lang.annotation.ElementType.PARAMETER,java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.FIELD})
+//@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.RUNTIME)
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+@Inherited
+public @interface JaxrsParameterDescribe {
+	abstract String value();
+}

+ 34 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/bean/NameIdPair.java

@@ -0,0 +1,34 @@
+package com.x.base.core.project.bean;
+
+public class NameIdPair {
+
+	public NameIdPair() {
+
+	}
+
+	public NameIdPair(String name, String id) {
+		this.name = name;
+		this.id = id;
+	}
+
+	private String name;
+
+	private String id;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+}

+ 66 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/bean/NameValueCountPair.java

@@ -0,0 +1,66 @@
+package com.x.base.core.project.bean;
+
+import java.util.Objects;
+
+public class NameValueCountPair {
+
+	private Object name;
+
+	private Object value;
+
+	private Long count;
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((count == null) ? 0 : count.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((value == null) ? 0 : value.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		NameValueCountPair other = (NameValueCountPair) obj;
+		if ((Objects.equals(this.getCount(), other.getCount())) && (Objects.equals(this.getName(), other.getName()))
+				&& (Objects.equals(this.getValue(), other.getValue()))) {
+			return true;
+		}
+		return false;
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public void setValue(Object value) {
+		this.value = value;
+	}
+
+	public Long getCount() {
+		return count;
+	}
+
+	public void setCount(Long count) {
+		this.count = count;
+	}
+
+	public Object getName() {
+		return name;
+	}
+
+	public void setName(Object name) {
+		this.name = name;
+	}
+
+}

+ 40 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/bean/NameValuePair.java

@@ -0,0 +1,40 @@
+package com.x.base.core.project.bean;
+
+import com.x.base.core.project.gson.GsonPropertyObject;
+
+public class NameValuePair extends GsonPropertyObject {
+
+	public NameValuePair() {
+
+	}
+
+	public NameValuePair(String name, Object value) {
+		this.name = name;
+		this.value = value;
+	}
+
+	private String name;
+
+	private Object value;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public <T> T getValue(Class<T> clz) {
+		return this.value == null ? null : (T) value;
+	}
+
+	public void setValue(Object value) {
+		this.value = value;
+	}
+
+}

+ 54 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/bean/PropertyObject.java

@@ -0,0 +1,54 @@
+package com.x.base.core.project.bean;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+
+public abstract class PropertyObject {
+	public void copyTo(Object o) throws Exception {
+		copyTo(o, false, new String[] {});
+	}
+
+	public void copyTo(Object o, String... excludes) throws Exception {
+		List<String> list = new ArrayList<String>();
+		for (String str : excludes) {
+			list.add(str);
+		}
+		copyTo(o, false, list);
+	}
+
+	public void copyTo(Object o, Collection<String> excludes) throws Exception {
+		this.copyTo(o, false, excludes);
+	}
+
+	public void copyTo(Object o, boolean ignoreNull) throws Exception {
+		copyTo(o, ignoreNull, new String[] {});
+	}
+
+	public void copyTo(Object o, boolean ignoreNull, String... excludes) throws Exception {
+		List<String> list = new ArrayList<String>();
+		for (String str : excludes) {
+			list.add(str);
+		}
+		copyTo(o, ignoreNull, list);
+	}
+
+	public void copyTo(Object o, boolean ignoreNull, Collection<String> excludes) throws Exception {
+		for (Field fld : FieldUtils.getAllFields(this.getClass())) {
+			if (!excludes.contains(fld.getName())) {
+				if (PropertyUtils.isReadable(this, fld.getName()) && PropertyUtils.isWriteable(o, fld.getName())) {
+					Object value = PropertyUtils.getProperty(this, fld.getName());
+					if (ignoreNull && (null == value)) {
+						continue;
+					}
+					PropertyUtils.setProperty(o, fld.getName(), value);
+				}
+			}
+		}
+	}
+
+}

Some files were not shown because too many files changed in this diff