Browse Source

第一次提交

jacky6024 7 years ago
commit
2dcfd67bd0
100 changed files with 8537 additions and 0 deletions
  1. 37 0
      urule-console/.classpath
  2. 36 0
      urule-console/.project
  3. 6 0
      urule-console/.settings/org.eclipse.core.resources.prefs
  4. 8 0
      urule-console/.settings/org.eclipse.jdt.core.prefs
  5. 4 0
      urule-console/.settings/org.eclipse.m2e.core.prefs
  6. 6 0
      urule-console/.settings/org.eclipse.wst.common.component
  7. 5 0
      urule-console/.settings/org.eclipse.wst.common.project.facet.core.xml
  8. 2 0
      urule-console/.settings/org.eclipse.wst.validation.prefs
  9. 74 0
      urule-console/pom.xml
  10. 55 0
      urule-console/src/main/java/com/bstek/urule/console/DefaultEnvironmentProvider.java
  11. 76 0
      urule-console/src/main/java/com/bstek/urule/console/DefaultKnowledgePackageService.java
  12. 65 0
      urule-console/src/main/java/com/bstek/urule/console/DefaultRepositoryInteceptor.java
  13. 43 0
      urule-console/src/main/java/com/bstek/urule/console/DefaultUser.java
  14. 36 0
      urule-console/src/main/java/com/bstek/urule/console/EnvironmentProvider.java
  15. 53 0
      urule-console/src/main/java/com/bstek/urule/console/EnvironmentUtils.java
  16. 31 0
      urule-console/src/main/java/com/bstek/urule/console/RepositoryInteceptor.java
  17. 34 0
      urule-console/src/main/java/com/bstek/urule/console/User.java
  18. 27 0
      urule-console/src/main/java/com/bstek/urule/console/exception/NoPermissionException.java
  19. 43 0
      urule-console/src/main/java/com/bstek/urule/console/repository/ClientConfig.java
  20. 37 0
      urule-console/src/main/java/com/bstek/urule/console/repository/Repository.java
  21. 293 0
      urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryBuilder.java
  22. 125 0
      urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryRefactor.java
  23. 58 0
      urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryResourceProvider.java
  24. 53 0
      urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryService.java
  25. 1067 0
      urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryServiceImpl.java
  26. 117 0
      urule-console/src/main/java/com/bstek/urule/console/repository/model/FileType.java
  27. 23 0
      urule-console/src/main/java/com/bstek/urule/console/repository/model/LibType.java
  28. 37 0
      urule-console/src/main/java/com/bstek/urule/console/repository/model/PermissionType.java
  29. 117 0
      urule-console/src/main/java/com/bstek/urule/console/repository/model/RepositoryFile.java
  30. 53 0
      urule-console/src/main/java/com/bstek/urule/console/repository/model/ResourceItem.java
  31. 63 0
      urule-console/src/main/java/com/bstek/urule/console/repository/model/ResourcePackage.java
  32. 24 0
      urule-console/src/main/java/com/bstek/urule/console/repository/model/Type.java
  33. 62 0
      urule-console/src/main/java/com/bstek/urule/console/repository/model/VersionFile.java
  34. 31 0
      urule-console/src/main/java/com/bstek/urule/console/repository/permission/PermissionService.java
  35. 225 0
      urule-console/src/main/java/com/bstek/urule/console/repository/permission/PermissionServiceImpl.java
  36. 23 0
      urule-console/src/main/java/com/bstek/urule/console/repository/permission/PermissionStore.java
  37. 46 0
      urule-console/src/main/java/com/bstek/urule/console/repository/updater/AbstractReferenceUpdater.java
  38. 105 0
      urule-console/src/main/java/com/bstek/urule/console/repository/updater/DecisionTableReferenceUpdater.java
  39. 105 0
      urule-console/src/main/java/com/bstek/urule/console/repository/updater/FlowDefinitionReferenceUpdater.java
  40. 25 0
      urule-console/src/main/java/com/bstek/urule/console/repository/updater/ReferenceUpdater.java
  41. 105 0
      urule-console/src/main/java/com/bstek/urule/console/repository/updater/RuleSetReferenceUpdater.java
  42. 105 0
      urule-console/src/main/java/com/bstek/urule/console/repository/updater/ScriptDecisionTableReferenceUpdater.java
  43. 59 0
      urule-console/src/main/java/com/bstek/urule/console/repository/updater/ScriptRuleSetReferenceUpdater.java
  44. 23 0
      urule-console/src/main/java/com/bstek/urule/console/repository/workspace_template.xml
  45. 53 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/BaseServletHandler.java
  46. 58 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/RenderPageServletHandler.java
  47. 38 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/RequestContext.java
  48. 45 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/RequestHolder.java
  49. 79 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/ResourceLoaderServletHandler.java
  50. 31 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/ServletHandler.java
  51. 113 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/URuleServlet.java
  52. 52 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/WriteJsonServletHandler.java
  53. 142 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/action/ActionServletHandler.java
  54. 80 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/client/ClientConfigServletHandler.java
  55. 291 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/common/CommonServletHandler.java
  56. 49 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/common/ErrorInfo.java
  57. 51 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/common/RefFile.java
  58. 38 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/common/ScriptErrorListener.java
  59. 23 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/common/ScriptType.java
  60. 52 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/constant/ConstantServletHandler.java
  61. 60 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/decisiontable/DecisiontableEditorServletHandler.java
  62. 60 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/decisiontree/DecisionTreeEditorServletHandler.java
  63. 36 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/Box.java
  64. 57 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/Diagram.java
  65. 52 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/DiagramContext.java
  66. 40 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/Edge.java
  67. 109 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/NodeInfo.java
  68. 219 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/ReteDiagramServletHandler.java
  69. 110 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/ReteNodeLayout.java
  70. 63 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/flow/FlowDefinitionWrapper.java
  71. 122 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/flow/RuleFlowDesignerServletHandler.java
  72. 441 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/frame/FrameServletHandler.java
  73. 81 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/knowledge/LoadKnowledgeServletHandler.java
  74. 56 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/parameter/ParameterServletHandler.java
  75. 152 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/permission/PermissionConfigServletHandler.java
  76. 188 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/permission/ProjectConfig.java
  77. 39 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/permission/UserPermission.java
  78. 69 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/respackage/HttpSessionKnowledgeCache.java
  79. 856 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/respackage/PackageServletHandler.java
  80. 58 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/respackage/SessionObject.java
  81. 63 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/ruleset/RuleSetServletEditorHandler.java
  82. 63 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/scorecard/ScorecardEditorServletHandler.java
  83. 60 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/scriptdecisiontable/ScriptDecisiontableEditorServletHandler.java
  84. 110 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/ul/ULEditorServletHandler.java
  85. 129 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/variable/VariableEditorServletHandler.java
  86. 170 0
      urule-console/src/main/java/com/bstek/urule/console/servlet/xml/XmlServletHandler.java
  87. 17 0
      urule-console/src/main/resources/html/action-editor.html
  88. 17 0
      urule-console/src/main/resources/html/client-config-editor.html
  89. 17 0
      urule-console/src/main/resources/html/constant-editor.html
  90. 18 0
      urule-console/src/main/resources/html/decisiontable-editor.html
  91. 18 0
      urule-console/src/main/resources/html/decisiontree-editor.html
  92. 19 0
      urule-console/src/main/resources/html/frame.html
  93. 18 0
      urule-console/src/main/resources/html/package-editor.html
  94. 17 0
      urule-console/src/main/resources/html/parameter-editor.html
  95. 17 0
      urule-console/src/main/resources/html/permission-config-editor.html
  96. 24 0
      urule-console/src/main/resources/html/rete-diagram.html
  97. 17 0
      urule-console/src/main/resources/html/rule-flow-designer.html
  98. 19 0
      urule-console/src/main/resources/html/ruleset-editor.html
  99. 21 0
      urule-console/src/main/resources/html/scorecard-editor.html
  100. 18 0
      urule-console/src/main/resources/html/scriptdecisiontable-editor.html

+ 37 - 0
urule-console/.classpath

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
+		<attributes>
+			<attribute name="owner.project.facets" value="java"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

+ 36 - 0
urule-console/.project

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>urule-console</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+	</natures>
+</projectDescription>

+ 6 - 0
urule-console/.settings/org.eclipse.core.resources.prefs

@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=utf-8
+encoding//src/test/resources=UTF-8
+encoding/<project>=UTF-8

+ 8 - 0
urule-console/.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.7

+ 4 - 0
urule-console/.settings/org.eclipse.m2e.core.prefs

@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

+ 6 - 0
urule-console/.settings/org.eclipse.wst.common.component

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+    <wb-module deploy-name="urule-console">
+        <wb-resource deploy-path="/" source-path="/src/main/java"/>
+        <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+    </wb-module>
+</project-modules>

+ 5 - 0
urule-console/.settings/org.eclipse.wst.common.project.facet.core.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+  <installed facet="jst.utility" version="1.0"/>
+  <installed facet="java" version="1.7"/>
+</faceted-project>

+ 2 - 0
urule-console/.settings/org.eclipse.wst.validation.prefs

@@ -0,0 +1,2 @@
+disabled=06target
+eclipse.preferences.version=1

+ 74 - 0
urule-console/pom.xml

@@ -0,0 +1,74 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.bstek.urule</groupId>
+    <artifactId>urule-parent</artifactId>
+    <version>2.0.0</version>
+  </parent>
+  <artifactId>urule-console</artifactId>
+  <version>2.0.4-SNAPSHOT</version>
+  <dependencies>
+  	<dependency>
+  		<groupId>com.bstek.urule</groupId>
+  		<artifactId>urule-core</artifactId>
+  		<version>2.0.4-SNAPSHOT</version>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.apache.jackrabbit</groupId>
+  		<artifactId>jackrabbit-core</artifactId>
+  		<version>2.13.3</version>
+  		<exclusions>
+  			<exclusion>
+  				<artifactId>derby</artifactId>
+  				<groupId>org.apache.derby</groupId>
+  			</exclusion>
+  		</exclusions>
+  	</dependency>
+  	<dependency>
+  		<groupId>javax.jcr</groupId>
+  		<artifactId>jcr</artifactId>
+  		<version>2.0</version>
+  	</dependency>
+  		<dependency>
+  		<groupId>javax.servlet</groupId>
+  		<artifactId>servlet-api</artifactId>
+  		<version>2.5</version>
+  		<scope>provided</scope>
+	</dependency>
+	<dependency>
+	    <groupId>commons-fileupload</groupId>
+	    <artifactId>commons-fileupload</artifactId>
+	    <version>1.3.2</version>
+	</dependency>
+	<dependency>
+		<groupId>org.apache.velocity</groupId>
+		<artifactId>velocity</artifactId>
+		<version>1.7</version>
+	</dependency>
+	<dependency>
+	    <groupId>org.apache.poi</groupId>
+	    <artifactId>poi-ooxml</artifactId>
+	    <version>3.14</version>
+	</dependency>
+  </dependencies>
+  
+	<developers>
+		<developer>
+			<name>Gaojie</name>
+			<email>jacky.gao@bstek.com</email>
+			<organization>Bstek</organization>
+			<organizationUrl>http://www.bstek.com</organizationUrl>
+		</developer>
+	</developers>
+	<scm>
+		<connection>https://github.com/youseries/urule.git</connection>
+		<developerConnection>https://github.com/youseries/urule.git</developerConnection>
+		<url>https://github.com/youseries/urule</url>
+	</scm>
+	<organization>
+		<name>Bstek</name>
+		<url>http://www.bstek.com</url>
+	</organization>	
+	<name>URule Console Project</name>
+	<url>https://github.com/youseries/urule/tree/master/urule-console</url>    
+</project>

+ 55 - 0
urule-console/src/main/java/com/bstek/urule/console/DefaultEnvironmentProvider.java

@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.bstek.urule.console.servlet.RequestContext;
+
+/**
+ * @author Jacky.gao
+ * @since 2016525
+ */
+public class DefaultEnvironmentProvider implements EnvironmentProvider {
+
+	@Override
+	public User getLoginUser(RequestContext context) {
+		DefaultUser user=new DefaultUser();
+		user.setCompanyId("bstek");
+		user.setUsername("admin");
+		user.setAdmin(true);
+		return user;
+	}
+
+	@Override
+	public List<User> getUsers() {
+		DefaultUser user1=new DefaultUser();
+		user1.setCompanyId("bstek");
+		user1.setUsername("user1");
+		DefaultUser user2=new DefaultUser();
+		user2.setCompanyId("bstek");
+		user2.setUsername("user2");
+		DefaultUser user3=new DefaultUser();
+		user3.setCompanyId("bstek");
+		user3.setUsername("user3");
+		List<User> users=new ArrayList<User>();
+		users.add(user1);
+		users.add(user2);
+		users.add(user3);
+		return users;
+	}
+}

+ 76 - 0
urule-console/src/main/java/com/bstek/urule/console/DefaultKnowledgePackageService.java

@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.builder.KnowledgeBase;
+import com.bstek.urule.builder.KnowledgeBuilder;
+import com.bstek.urule.builder.ResourceBase;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.repository.model.ResourceItem;
+import com.bstek.urule.console.repository.model.ResourcePackage;
+import com.bstek.urule.runtime.KnowledgePackage;
+import com.bstek.urule.runtime.service.KnowledgePackageService;
+
+/**
+ * @author Jacky.gao
+ * @since 2016622
+ */
+public class DefaultKnowledgePackageService implements KnowledgePackageService{
+	private KnowledgeBuilder knowledgeBuilder;
+	private RepositoryService repositoryService;
+	
+	public KnowledgePackage buildKnowledgePackage(String packageInfo) throws IOException{
+		try{
+			String[] info=packageInfo.split("/");
+			if(info.length!=2){
+				throw new RuleException("PackageInfo ["+packageInfo+"] is invalid. Correct such as \"projectName/packageId\".");
+			}
+			String project=info[0];
+			String packageId=info[1];
+			List<ResourcePackage> packages=repositoryService.loadProjectResourcePackages(project);
+			List<ResourceItem> list=null;
+			for(ResourcePackage p:packages){
+				if(p.getId().equals(packageId)){
+					list=p.getResourceItems();
+					break;
+				}
+			}
+			if(list==null){
+				throw new RuleException("PackageId ["+packageId+"] was not found in project ["+project+"].");
+			}
+			ResourceBase resourceBase=knowledgeBuilder.newResourceBase();
+			for(ResourceItem item:list){
+				resourceBase.addResource(item.getPath(),item.getVersion());
+			}
+			KnowledgeBase knowledgeBase=knowledgeBuilder.buildKnowledgeBase(resourceBase);
+			KnowledgePackage knowledgePackage=knowledgeBase.getKnowledgePackage();
+			return knowledgePackage;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+
+	public void setKnowledgeBuilder(KnowledgeBuilder knowledgeBuilder) {
+		this.knowledgeBuilder = knowledgeBuilder;
+	}
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+}

+ 65 - 0
urule-console/src/main/java/com/bstek/urule/console/DefaultRepositoryInteceptor.java

@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console;
+
+
+/**
+ * @author Jacky.gao
+ * @since 2016830
+ */
+public class DefaultRepositoryInteceptor implements RepositoryInteceptor {
+
+	@Override
+	public void readFile(String file) {
+		
+	}
+
+	@Override
+	public void saveFile(String file, String content) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void createFile(String file,String content) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void deleteFile(String file) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void renameFile(String oldFileName, String newFileName) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void createDir(String dir) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void createProject(String project) {
+		// TODO Auto-generated method stub
+		
+	}
+}

+ 43 - 0
urule-console/src/main/java/com/bstek/urule/console/DefaultUser.java

@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console;
+/**
+ * @author Jacky.gao
+ * @since 2016525
+ */
+public class DefaultUser implements User{
+	private String username;
+	private String companyId;
+	private boolean isAdmin;
+	public String getUsername() {
+		return username;
+	}
+	public void setUsername(String username) {
+		this.username = username;
+	}
+	public String getCompanyId() {
+		return companyId;
+	}
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+	public boolean isAdmin() {
+		return isAdmin;
+	}
+	public void setAdmin(boolean isAdmin) {
+		this.isAdmin = isAdmin;
+	}
+}

+ 36 - 0
urule-console/src/main/java/com/bstek/urule/console/EnvironmentProvider.java

@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console;
+
+import java.util.List;
+
+import com.bstek.urule.console.servlet.RequestContext;
+
+/**
+ * @author Jacky.gao
+ * @since 2015327
+ */
+public interface EnvironmentProvider {
+	/**
+	 * @return 返回当前登录用户
+	 */
+	User getLoginUser(RequestContext context);
+	
+	/**
+	 * @return 返回当前系统当中用户集合 ,供配置资源库权限使用
+	 */
+	List<User> getUsers();
+}

+ 53 - 0
urule-console/src/main/java/com/bstek/urule/console/EnvironmentUtils.java

@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console;
+
+import java.util.Collection;
+
+import org.springframework.context.ApplicationContext;
+
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.servlet.RequestContext;
+
+
+/**
+ * @author Jacky.gao
+ * @since 201516
+ */
+public class EnvironmentUtils{
+	private static EnvironmentProvider environmentProvider;
+	public static User getLoginUser(RequestContext context){
+		if(environmentProvider==null){
+			initEnvironmentProvider();
+		}
+		return environmentProvider.getLoginUser(context);
+	}
+	public static void initEnvironmentProvider(){
+		ApplicationContext context=Utils.getApplicationContext();
+		Collection<EnvironmentProvider> providers=context.getBeansOfType(EnvironmentProvider.class).values();
+		if(providers.size()==0){
+			environmentProvider=new DefaultEnvironmentProvider();
+		}else{
+			environmentProvider = providers.iterator().next();			
+		}
+	}
+	public static EnvironmentProvider getEnvironmentProvider(){
+		if(environmentProvider==null){
+			initEnvironmentProvider();
+		}
+		return environmentProvider;
+	}
+}

+ 31 - 0
urule-console/src/main/java/com/bstek/urule/console/RepositoryInteceptor.java

@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console;
+
+
+/**
+ * @author Jacky.gao
+ * @since 2016830
+ */
+public interface RepositoryInteceptor {
+	void readFile(String file);
+	void saveFile(String file,String content);
+	void createFile(String file,String content);
+	void deleteFile(String file);
+	void renameFile(String oldFileName,String newFileName);
+	void createDir(String dir);
+	void createProject(String project);
+}

+ 34 - 0
urule-console/src/main/java/com/bstek/urule/console/User.java

@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console;
+/**
+ * @author Jacky.gao
+ * @since 201557
+ */
+public interface User {
+	/**
+	 * @return 用户名
+	 */
+	String getUsername();
+	/**
+	 * @return 所在公司ID
+	 */
+	String getCompanyId();
+	/**
+	 * @return 是否为管理员
+	 */
+	boolean isAdmin();
+}

+ 27 - 0
urule-console/src/main/java/com/bstek/urule/console/exception/NoPermissionException.java

@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.exception;
+
+/**
+ * @author Jacky.gao
+ * @since 201691
+ */
+public class NoPermissionException extends RuntimeException {
+	private static final long serialVersionUID = 441877650698078466L;
+	public NoPermissionException() {
+		super("Permission denied!");
+	}
+}

+ 43 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/ClientConfig.java

@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository;
+/**
+ * @author Jacky.gao
+ * @since 2016811
+ */
+public class ClientConfig {
+	private String name;
+	private String client;
+	private String project;
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getClient() {
+		return client;
+	}
+	public void setClient(String client) {
+		this.client = client;
+	}
+	public String getProject() {
+		return project;
+	}
+	public void setProject(String project) {
+		this.project = project;
+	}
+}

+ 37 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/Repository.java

@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository;
+
+import java.util.List;
+
+import com.bstek.urule.console.repository.model.RepositoryFile;
+
+public class Repository {
+	private RepositoryFile rootFile;
+	private List<String> projectNames;
+	public RepositoryFile getRootFile() {
+		return rootFile;
+	}
+	public void setRootFile(RepositoryFile rootFile) {
+		this.rootFile = rootFile;
+	}
+	public List<String> getProjectNames() {
+		return projectNames;
+	}
+	public void setProjectNames(List<String> projectNames) {
+		this.projectNames = projectNames;
+	}
+}

+ 293 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryBuilder.java

@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+import javax.jcr.RepositoryException;
+import javax.servlet.ServletContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.AccessManagerConfig;
+import org.apache.jackrabbit.core.config.BeanConfig;
+import org.apache.jackrabbit.core.config.ClusterConfig;
+import org.apache.jackrabbit.core.config.DataSourceConfig;
+import org.apache.jackrabbit.core.config.LoginModuleConfig;
+import org.apache.jackrabbit.core.config.PersistenceManagerConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
+import org.apache.jackrabbit.core.config.SecurityConfig;
+import org.apache.jackrabbit.core.config.SecurityManagerConfig;
+import org.apache.jackrabbit.core.config.VersioningConfig;
+import org.apache.jackrabbit.core.data.DataStore;
+import org.apache.jackrabbit.core.data.DataStoreFactory;
+import org.apache.jackrabbit.core.data.FileDataStore;
+import org.apache.jackrabbit.core.fs.FileSystem;
+import org.apache.jackrabbit.core.fs.FileSystemException;
+import org.apache.jackrabbit.core.fs.FileSystemFactory;
+import org.apache.jackrabbit.core.fs.local.LocalFileSystem;
+import org.apache.jackrabbit.core.query.QueryHandlerFactory;
+import org.apache.jackrabbit.core.state.DefaultISMLocking;
+import org.apache.jackrabbit.core.state.ISMLocking;
+import org.apache.jackrabbit.core.state.ISMLockingFactory;
+import org.apache.jackrabbit.core.util.CooperativeFileLock;
+import org.apache.jackrabbit.core.util.RepositoryLockMechanism;
+import org.apache.jackrabbit.core.util.RepositoryLockMechanismFactory;
+import org.apache.jackrabbit.core.util.db.ConnectionFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.web.context.WebApplicationContext;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.bstek.urule.RuleException;
+
+/**
+ * @author Jacky.gao
+ * @since 2016524
+ */
+public class RepositoryBuilder implements InitializingBean,ApplicationContextAware{
+	private String repoHomeDir;
+	private Element workspaceTemplate;
+	private RepositoryImpl repository;
+	private String repositoryXml;
+	private ApplicationContext applicationContext;
+	private Logger log=Logger.getLogger(RepositoryBuilder.class.getName());
+	public RepositoryImpl getRepository() {
+		return repository;
+	}
+
+	private SecurityConfig buildSecurityConfig(){
+		SecurityConfig securityConfig=new SecurityConfig("uruleRepoSecurity",buildSecurityManagerConfig(),buildAccessManagerConfig(),buildLoginModuleConfig());
+		return securityConfig;
+	}
+	
+	private RepositoryLockMechanismFactory buildRepositoryLockMechanismFactory(){
+		return new RepositoryLockMechanismFactory(){
+			public RepositoryLockMechanism getRepositoryLockMechanism() throws RepositoryException {
+				return new CooperativeFileLock();
+			}
+		};
+	}
+	
+	private FileSystemFactory buildFileSystemFactory(final String dirName){
+		return new FileSystemFactory() {
+            public FileSystem getFileSystem() throws RepositoryException {
+                try {
+                	LocalFileSystem fs = new LocalFileSystem();
+                    fs.setPath(""+repoHomeDir+"/"+dirName);
+                    fs.init();
+                    return fs;
+                } catch (FileSystemException e) {
+                    throw new RepositoryException("File system initialization failure.", e);
+                }
+            }
+        };
+	}
+	
+	private DataStoreFactory buildDataStoreFactory(){
+		return new DataStoreFactory(){
+			public DataStore getDataStore() throws RepositoryException {
+				FileDataStore datastore=new FileDataStore();
+				datastore.setPath(""+repoHomeDir+"/repository/datastore");
+				datastore.setMinRecordLength(100);
+				return null;
+			}
+		};
+	}
+	
+	private VersioningConfig buildVersioningConfig(){
+		String homeDir=""+repoHomeDir+"/version";
+		FileSystemFactory fileSystemFactory=buildFileSystemFactory("version");
+		PersistenceManagerConfig persistenceManagerConfig=buildPersistenceManagerConfig();
+		ISMLockingFactory ismLockingFactory=buildISMLockingFactory();
+		VersioningConfig versioningConfig=new VersioningConfig(homeDir,fileSystemFactory,persistenceManagerConfig,ismLockingFactory);
+		return versioningConfig;
+	}
+	
+	private ISMLockingFactory buildISMLockingFactory(){
+		return new ISMLockingFactory(){
+			public ISMLocking getISMLocking() throws RepositoryException {
+				return new DefaultISMLocking();
+			}
+		};
+	}
+	
+	private PersistenceManagerConfig buildPersistenceManagerConfig(){
+		Properties prop=new Properties();
+		BeanConfig beanConfig=new BeanConfig("org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager",prop);
+		PersistenceManagerConfig persistenceManagerConfig=new PersistenceManagerConfig(beanConfig);
+		return persistenceManagerConfig;
+	}
+	
+	private SecurityManagerConfig buildSecurityManagerConfig(){
+		Properties prop=new Properties();
+		BeanConfig beanConfig=new BeanConfig("org.apache.jackrabbit.core.security.simple.SimpleSecurityManager",prop);
+		SecurityManagerConfig securityManagerConfig=new SecurityManagerConfig(beanConfig,"default",null);
+		return securityManagerConfig;
+	}
+	
+	private AccessManagerConfig buildAccessManagerConfig(){
+		Properties prop=new Properties();
+		BeanConfig beanConfig=new BeanConfig("org.apache.jackrabbit.core.security.simple.SimpleAccessManager",prop);
+		AccessManagerConfig accessManagerConfig=new AccessManagerConfig(beanConfig);
+		return accessManagerConfig;
+	}
+	
+	private LoginModuleConfig buildLoginModuleConfig(){
+		Properties prop=new Properties();
+		prop.put("anonymousId", "anonymous");
+		prop.put("adminId", "admin");
+		BeanConfig beanConfig=new BeanConfig("org.apache.jackrabbit.core.security.simple.SimpleLoginModule",prop);
+		LoginModuleConfig loginModuleConfig=new LoginModuleConfig(beanConfig);
+		return loginModuleConfig;
+	}
+	
+	private void initRepositoryByXml()throws Exception {
+		InputStream inputStream=null;
+		try{
+			inputStream=this.applicationContext.getResource(repositoryXml).getInputStream();
+			String tempRepoHomeDir=System.getProperty("java.io.tmpdir");
+			if(StringUtils.isNotBlank(tempRepoHomeDir) && tempRepoHomeDir.length()>1){
+				if(tempRepoHomeDir.endsWith("/") || tempRepoHomeDir.endsWith("\\")){
+					tempRepoHomeDir+="urule-temp-repo-home/";
+				}else{
+					tempRepoHomeDir+="/urule-temp-repo-home/";					
+				}
+				File tempDir=new File(tempRepoHomeDir);
+				clearTempDir(tempDir);
+			}else{
+				tempRepoHomeDir="";
+			}
+			RepositoryConfig repositoryConfig = RepositoryConfig.create(inputStream,tempRepoHomeDir);
+			repository=RepositoryImpl.create(repositoryConfig);
+		}finally{
+			if(inputStream!=null){
+				inputStream.close();
+			}
+		}
+	}
+	
+	private void clearTempDir(File file){
+		if(file.isDirectory()){
+			for(File childFile:file.listFiles()){
+				clearTempDir(childFile);
+			}
+		}
+		file.delete();
+	}
+	
+	private void initDefaultRepository()throws Exception {
+		SecurityConfig securityConfig=buildSecurityConfig();
+		FileSystemFactory fileSystemFactory=buildFileSystemFactory("repository");
+		String workspaceDirectory=""+repoHomeDir+"/workspaces";
+		String workspaceConfigDirectory=null;
+		String defaultWorkspace="default";
+		int workspaceMaxIdleTime=0;
+		VersioningConfig versioningConfig=buildVersioningConfig();
+		QueryHandlerFactory queryHandlerFactory=null;
+		ClusterConfig clusterConfig=null;
+		DataStoreFactory dataStoreFactory=buildDataStoreFactory();
+		RepositoryLockMechanismFactory repositoryLockMechanismFactory=buildRepositoryLockMechanismFactory();
+		DataSourceConfig dataSourceConfig=new DataSourceConfig();
+		ConnectionFactory connectionFactory=new ConnectionFactory();
+		RepositoryConfigurationParser repositoryConfigurationParser=new RepositoryConfigurationParser(new Properties());
+		initWorkspaceTemplate();
+		RepositoryConfig repositoryConfig = new RepositoryConfig(repoHomeDir, securityConfig,
+				fileSystemFactory, workspaceDirectory,
+				workspaceConfigDirectory, defaultWorkspace,
+				workspaceMaxIdleTime, workspaceTemplate, versioningConfig,
+				queryHandlerFactory, clusterConfig, dataStoreFactory,
+				repositoryLockMechanismFactory, dataSourceConfig,
+				connectionFactory, repositoryConfigurationParser);
+		repositoryConfig.init();
+		repository=RepositoryImpl.create(repositoryConfig);
+	}
+	
+	private void initWorkspaceTemplate(){
+		InputStream inputStream=null;
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		try {
+			DocumentBuilder builder = factory.newDocumentBuilder();
+			inputStream=applicationContext.getResource("classpath:com/bstek/urule/console/repository/workspace_template.xml").getInputStream();
+			Document doc = builder.parse(inputStream);
+			workspaceTemplate=doc.getDocumentElement();
+		} catch (Exception e) {
+			throw new RuleException(e);
+		} finally {
+			IOUtils.closeQuietly(inputStream);
+		}
+	}
+	
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext=applicationContext;
+	}
+	
+	private void initRepositoryDir(ApplicationContext applicationContext){
+		if(applicationContext instanceof WebApplicationContext){
+			WebApplicationContext context=(WebApplicationContext)applicationContext;
+			ServletContext servletContext=context.getServletContext();
+			File file=new File(repoHomeDir);
+			if(!file.exists()){
+				repoHomeDir=servletContext.getRealPath(repoHomeDir);
+			}
+			file=new File(repoHomeDir);
+			if(!file.exists()){
+				throw new RuleException("Repository root dir "+repoHomeDir+" is not exist.");
+			}
+		}else{
+			log.info("Current is not a standard web container,so can't resolve real path for repo home dir.");
+		}
+		log.info("Use \""+repoHomeDir+"\" as urule repository home directory.");
+	}
+	public void afterPropertiesSet() throws Exception {
+		if(StringUtils.isNotBlank(repoHomeDir) && !repoHomeDir.equals("${urule.repository.dir}")){
+			initRepositoryDir(applicationContext);			
+		}
+		if(StringUtils.isEmpty(repositoryXml)){
+			if(StringUtils.isBlank(repoHomeDir)){
+				throw new RuleException("You need config \"urule.repository.dir\" property for set repository home dir.");
+			}
+			initDefaultRepository();
+		}else{
+			log.info("Build repository from user custom xml file...");
+			initRepositoryByXml();
+		}
+	}
+	public void setRepoHomeDir(String repoHomeDir) {
+		this.repoHomeDir = repoHomeDir;
+	}
+	
+	
+	public void setRepositoryXml(String repositoryXml) {
+		this.repositoryXml = repositoryXml;
+	}
+	
+	public void destroy(){
+		System.out.println("Shutdown repository...");
+		repository.shutdown();
+		System.out.println("Shutdown repository completed...");
+	}
+}

+ 125 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryRefactor.java

@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+
+import org.apache.tika.io.IOUtils;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.console.repository.model.FileType;
+import com.bstek.urule.console.repository.updater.ReferenceUpdater;
+
+/**
+ * @author Jacky.gao
+ * @since 2016525
+ */
+public class RepositoryRefactor {
+	private RepositoryService repositoryService;
+	private Collection<ReferenceUpdater> updaters;
+	public RepositoryRefactor(RepositoryService repositoryService,Collection<ReferenceUpdater> updaters) {
+		this.repositoryService=repositoryService;
+		this.updaters=updaters;
+	}
+	public void rename(Node rootNode,String path,String newpath,String createUser){
+		List<String> referenceFiles=getFiles(rootNode,path);
+		for(String nodePath:referenceFiles){
+			for(ReferenceUpdater updater:updaters){
+				if(updater.support(nodePath)){
+					InputStream inputStream=repositoryService.readFile(newpath,null);
+					try {
+						String content = IOUtils.toString(inputStream);
+						inputStream.close();
+						String newContent=updater.update(path, path, content);
+						if(newContent!=null){
+							repositoryService.saveFile(newpath,createUser,newContent, false,null);
+						}
+					} catch (IOException e) {
+						throw new RuleException(e);
+					}
+				}
+			}
+		}
+	}
+	
+	public List<String> getReferenceFiles(Node rootNode,String path){
+		List<String> referenceFiles=new ArrayList<String>();
+		List<String> files=getFiles(rootNode, path);
+		for(String nodePath:files){
+			InputStream inputStream=repositoryService.readFile(nodePath,null);
+			try {
+				String content = IOUtils.toString(inputStream);
+				inputStream.close();
+				boolean contain=content.contains(path);
+				if(contain){
+					referenceFiles.add(nodePath);
+				}
+			} catch (IOException e) {
+				throw new RuleException(e);
+			}
+		}
+		return referenceFiles;
+	}
+		
+	public List<String> getFiles(Node rootNode,String path){
+		String project=getProject(path);
+		try{
+			List<String> list=new ArrayList<String>();
+			Node projectNode=rootNode.getNode(project);		
+			buildPath(list, projectNode);
+			return list;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+	private void buildPath(List<String> list, Node parentNode) throws RepositoryException {
+		NodeIterator nodeIterator=parentNode.getNodes();
+		while(nodeIterator.hasNext()){
+			Node node=nodeIterator.nextNode();
+			String nodePath=node.getPath();
+			if(nodePath.endsWith(FileType.Ruleset.toString())){
+				list.add(nodePath);
+			}else if(nodePath.endsWith(FileType.UL.toString())){
+				list.add(nodePath);
+			}else if(nodePath.endsWith(FileType.DecisionTable.toString())){
+				list.add(nodePath);
+			}else if(nodePath.endsWith(FileType.ScriptDecisionTable.toString())){
+				list.add(nodePath);
+			}else if(nodePath.endsWith(FileType.DecisionTree.toString())){
+				list.add(nodePath);					
+			}else if(nodePath.endsWith(FileType.RuleFlow.toString())){
+				list.add(nodePath);					
+			}
+			buildPath(list,node);
+		}
+	}
+	
+	private String getProject(String path){
+		if(path.startsWith("/")){
+			path=path.substring(1);
+		}
+		int pos=path.indexOf("/");
+		return path.substring(0,pos);
+	}
+}

+ 58 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryResourceProvider.java

@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.builder.resource.Resource;
+import com.bstek.urule.builder.resource.ResourceProvider;
+
+/**
+ * @author Jacky.gao
+ * @since 2015325
+ */
+public class RepositoryResourceProvider implements ResourceProvider {
+	public static final String JCR="jcr:";
+	private RepositoryService repositoryService;
+	public Resource provide(String path,String version) {
+		String newpath=path.substring(4,path.length());
+		InputStream inputStream=null;
+		if(StringUtils.isEmpty(version) || version.equals("LATEST")){
+			inputStream=repositoryService.readFile(newpath,null);			
+		}else{
+			inputStream=repositoryService.readFile(newpath,version);						
+		}
+		try {
+			String content=IOUtils.toString(inputStream,"utf-8");
+			IOUtils.closeQuietly(inputStream);
+			return new Resource(content,path);
+		} catch (IOException e) {
+			throw new RuleException(e);
+		}
+	}
+
+	public boolean support(String path) {
+		return path.startsWith(JCR);
+	}
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+}

+ 53 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryService.java

@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+
+import com.bstek.urule.console.User;
+import com.bstek.urule.console.repository.model.FileType;
+import com.bstek.urule.console.repository.model.RepositoryFile;
+import com.bstek.urule.console.repository.model.ResourcePackage;
+import com.bstek.urule.console.repository.model.VersionFile;
+import com.bstek.urule.console.servlet.permission.UserPermission;
+
+/**
+ * @author Jacky.gao
+ * @since 2015324
+ */
+public interface RepositoryService {
+	public static final String BEAN_ID="urule.repositoryService";
+	boolean fileExistCheck(String filePath);
+	RepositoryFile createProject(String projectName,User user,boolean classify);
+	void createDir(String path,User user);
+	void createFile(String path,String content,String createUser);
+	void saveFile(String path,String content,String createUser,boolean newVersion,String versionComment);
+	void deleteFile(String path);
+	Repository loadRepository(String project,String companyId,boolean classify,FileType[] types,String searchFileName);
+	List<RepositoryFile> loadProject(String companyId);
+	void fileRename(String path, String newPath);
+	List<String> getReferenceFiles(String path);
+	InputStream readFile(String path,String version);
+	List<ResourcePackage> loadProjectResourcePackages(String project) throws Exception;
+	List<VersionFile> getVersionFiles(String path);
+	void exportXml(String projectPath,OutputStream outputStream);
+	void importXml(InputStream inputStream,boolean overwrite);
+	List<RepositoryFile> getDirectories(String project) throws Exception;
+	List<ClientConfig> loadClientConfigs(String project);
+	List<UserPermission> loadResourceSecurityConfigs(String companyId);
+}

+ 1067 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/RepositoryServiceImpl.java

@@ -0,0 +1,1067 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+import javax.jcr.Binary;
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+import javax.jcr.version.VersionManager;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.value.BinaryImpl;
+import org.apache.jackrabbit.value.DateValue;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.DefaultRepositoryInteceptor;
+import com.bstek.urule.console.RepositoryInteceptor;
+import com.bstek.urule.console.User;
+import com.bstek.urule.console.exception.NoPermissionException;
+import com.bstek.urule.console.repository.model.FileType;
+import com.bstek.urule.console.repository.model.LibType;
+import com.bstek.urule.console.repository.model.RepositoryFile;
+import com.bstek.urule.console.repository.model.ResourceItem;
+import com.bstek.urule.console.repository.model.ResourcePackage;
+import com.bstek.urule.console.repository.model.Type;
+import com.bstek.urule.console.repository.model.VersionFile;
+import com.bstek.urule.console.repository.permission.PermissionService;
+import com.bstek.urule.console.repository.updater.ReferenceUpdater;
+import com.bstek.urule.console.servlet.permission.ProjectConfig;
+import com.bstek.urule.console.servlet.permission.UserPermission;
+
+/**
+ * @author Jacky.gao
+ * @since 2016524
+ */
+public class RepositoryServiceImpl implements RepositoryService, ApplicationContextAware {
+	public static final String RES_PACKGE_FILE="___res__package__file__";
+	public static final String CLIENT_CONFIG_FILE="___client_config__file__";
+	public static final String RESOURCE_SECURITY_CONFIG_FILE="___resource_security_config__file__";
+	private final String DATA = "_data";
+	private final String DIR_TAG = "_dir";
+	private final String FILE = "_file";
+	private final String CRATE_USER = "_create_user";
+	private final String CRATE_DATE = "_create_date";
+	private final String VERSION_COMMENT="_version_comment";
+	private final String COMPANY_ID="_company_id";
+
+	private RepositoryBuilder repositoryBuilder;
+	private RepositoryImpl repository;
+	private Session session;
+	private VersionManager versionManager;
+	private RepositoryRefactor refactor;
+	private RepositoryInteceptor repositoryInteceptor;
+	private PermissionService permissionService;
+	
+	@Override
+	public List<UserPermission> loadResourceSecurityConfigs(String companyId) {
+		try{
+			List<UserPermission> configs=new ArrayList<UserPermission>();
+			String filePath=RESOURCE_SECURITY_CONFIG_FILE+(companyId == null ? "" : companyId);
+			Node rootNode=getRootNode();
+			if (!rootNode.hasNode(filePath)) {
+				createFileNode(filePath, "<?xml version=\"1.0\" encoding=\"utf-8\"?><user-permission></user-permission>",null,false);
+				return configs;
+			}
+			Node fileNode = rootNode.getNode(filePath);
+			Property property = fileNode.getProperty(DATA);
+			Binary fileBinary = property.getBinary();
+			InputStream inputStream = fileBinary.getStream();
+			String content = IOUtils.toString(inputStream, "utf-8");
+			inputStream.close();
+			Document document = DocumentHelper.parseText(content);
+			Element rootElement = document.getRootElement();
+			for (Object obj : rootElement.elements()) {
+				if (!(obj instanceof Element)) {
+					continue;
+				}
+				Element element = (Element) obj;
+				if (!element.getName().equals("user-permission")) {
+					continue;
+				}
+				UserPermission userResource=new UserPermission();
+				userResource.setUsername(element.attributeValue("username"));
+				userResource.setProjectConfigs(parseProjectConfigs(element));
+				configs.add(userResource);
+			}
+			return configs;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+	
+	private List<ProjectConfig> parseProjectConfigs(Element element){
+		List<ProjectConfig> list=new ArrayList<ProjectConfig>();
+		for (Object obj : element.elements()) {
+			if (!(obj instanceof Element)) {
+				continue;
+			}
+			Element ele = (Element) obj;
+			if (!ele.getName().equals("project-config")) {
+				continue;
+			}
+			ProjectConfig config=new ProjectConfig();
+			config.setProject(ele.attributeValue("project"));
+			config.setReadProject(parseBooleanValue(ele, "read-project"));
+			
+			config.setReadPackage(parseBooleanValue(ele, "read-package"));
+			config.setWritePackage(parseBooleanValue(ele, "write-package"));
+			
+			config.setReadVariableFile(parseBooleanValue(ele, "read-variable-file"));
+			config.setWriteVariableFile(parseBooleanValue(ele, "write-variable-file"));
+			
+			config.setReadParameterFile(parseBooleanValue(ele, "read-parameter-file"));
+			config.setWriteParameterFile(parseBooleanValue(ele, "write-parameter-file"));
+			
+			config.setReadConstantFile(parseBooleanValue(ele, "read-constant-file"));
+			config.setWriteConstantFile(parseBooleanValue(ele, "write-constant-file"));
+			
+			config.setReadActionFile(parseBooleanValue(ele, "read-action-file"));
+			config.setWriteActionFile(parseBooleanValue(ele, "write-action-file"));
+			
+			config.setReadRuleFile(parseBooleanValue(ele, "read-rule-file"));
+			config.setWriteRuleFile(parseBooleanValue(ele, "write-rule-file"));
+			
+			config.setReadScorecardFile(parseBooleanValue(ele, "read-scorecard-file"));
+			config.setWriteScorecardFile(parseBooleanValue(ele, "write-scorecard-file"));
+			
+			config.setReadDecisionTableFile(parseBooleanValue(ele, "read-decision-table-file"));
+			config.setWriteDecisionTableFile(parseBooleanValue(ele, "write-decision-table-file"));
+			
+			config.setReadDecisionTreeFile(parseBooleanValue(ele, "read-decision-tree-file"));
+			config.setWriteDecisionTreeFile(parseBooleanValue(ele, "write-decision-tree-file"));
+			
+			config.setReadFlowFile(parseBooleanValue(ele, "read-flow-file"));
+			config.setWriteFlowFile(parseBooleanValue(ele, "write-flow-file"));
+			list.add(config);
+		}
+		return list;
+	}
+	
+	private boolean parseBooleanValue(Element element,String attributeName){
+		if(element.attributeValue(attributeName)!=null){
+			return Boolean.valueOf(element.attributeValue(attributeName));
+		}
+		return false;
+	}
+	
+	@Override
+	public List<ClientConfig> loadClientConfigs(String project) {
+		if(!permissionService.isAdmin()){
+			throw new NoPermissionException();
+		}
+		
+		try{
+			List<ClientConfig> clients=new ArrayList<ClientConfig>();
+			Node rootNode=getRootNode();
+			String filePath = processPath(project) + "/" + CLIENT_CONFIG_FILE;
+			if (!rootNode.hasNode(filePath)) {
+				createFile(filePath, "<?xml version=\"1.0\" encoding=\"utf-8\"?><client-config></client-config>",null);
+				return clients;
+			}
+			Node fileNode = rootNode.getNode(filePath);
+			Property property = fileNode.getProperty(DATA);
+			Binary fileBinary = property.getBinary();
+			InputStream inputStream = fileBinary.getStream();
+			String content = IOUtils.toString(inputStream, "utf-8");
+			inputStream.close();
+			Document document = DocumentHelper.parseText(content);
+			Element rootElement = document.getRootElement();
+			for (Object obj : rootElement.elements()) {
+				if (!(obj instanceof Element)) {
+					continue;
+				}
+				Element element = (Element) obj;
+				if (!element.getName().equals("item")) {
+					continue;
+				}
+				ClientConfig client = new ClientConfig();
+				client.setName(element.attributeValue("name"));
+				client.setClient(element.attributeValue("client"));
+				client.setProject(project);
+				clients.add(client);
+			}
+			return clients;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+
+	public List<VersionFile> getVersionFiles(String path) {
+		path = processPath(path);
+		try {
+			Node rootNode=getRootNode();
+			if (!rootNode.hasNode(path)) {
+				throw new RuleException("File [" + path + "] not exist.");
+			}
+			List<VersionFile> files = new ArrayList<VersionFile>();
+			Node fileNode = rootNode.getNode(path);
+			VersionHistory versionHistory = versionManager.getVersionHistory(fileNode.getPath());
+			VersionIterator iterator = versionHistory.getAllVersions();
+			while (iterator.hasNext()) {
+				Version version = iterator.nextVersion();
+				String versionName = version.getName();
+				if (versionName.startsWith("jcr:")) {
+					continue; // skip root version
+				}
+				Node fnode = version.getFrozenNode();
+				VersionFile file = new VersionFile();
+				file.setName(version.getName());
+				file.setPath(fileNode.getPath());
+				Property prop = fnode.getProperty(CRATE_USER);
+				file.setCreateUser(prop.getString());
+				prop = fnode.getProperty(CRATE_DATE);
+				file.setCreateDate(prop.getDate().getTime());
+				
+				if(fnode.hasProperty(VERSION_COMMENT)){
+					prop=fnode.getProperty(VERSION_COMMENT);
+					file.setComment(prop.getString());
+				}
+				
+				files.add(file);
+			}
+			return files;
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+
+	public List<RepositoryFile> getDirectories(String project) throws Exception {
+		Node rootNode=getRootNode();
+		NodeIterator nodeIterator = rootNode.getNodes();
+		Node targetProjectNode = null;
+		while (nodeIterator.hasNext()) {
+			Node projectNode = nodeIterator.nextNode();
+			if (!projectNode.hasProperty(FILE)) {
+				continue;
+			}
+			String projectName = projectNode.getName();
+			if (project != null && !project.equals(projectName)) {
+				continue;
+			}
+			targetProjectNode = projectNode;
+			break;
+		}
+		if (targetProjectNode == null) {
+			throw new RuleException("Project [" + project + "] not exist.");
+		}
+		List<RepositoryFile> fileList = new ArrayList<RepositoryFile>();
+		RepositoryFile root = new RepositoryFile();
+		root.setName("根目录");
+		String projectPath = targetProjectNode.getPath();
+		root.setFullPath(projectPath);
+		fileList.add(root);
+		NodeIterator projectNodeIterator = targetProjectNode.getNodes();
+		while (projectNodeIterator.hasNext()) {
+			Node dirNode = projectNodeIterator.nextNode();
+			if (!dirNode.hasProperty(DIR_TAG)) {
+				continue;
+			}
+			RepositoryFile file = new RepositoryFile();
+			file.setName(dirNode.getPath().substring(projectPath.length()));
+			file.setFullPath(dirNode.getPath());
+			fileList.add(file);
+			buildDirectories(dirNode, fileList, projectPath);
+		}
+		return fileList;
+	}
+
+	private void buildDirectories(Node node, List<RepositoryFile> fileList, String projectPath) throws Exception {
+		NodeIterator nodeIterator = node.getNodes();
+		while (nodeIterator.hasNext()) {
+			Node dirNode = nodeIterator.nextNode();
+			if (!dirNode.hasProperty(FILE)) {
+				continue;
+			}
+			if (!dirNode.hasProperty(DIR_TAG)) {
+				continue;
+			}
+			RepositoryFile file = new RepositoryFile();
+			file.setName(dirNode.getPath().substring(projectPath.length()));
+			file.setFullPath(dirNode.getPath());
+			buildDirectories(dirNode, fileList, projectPath);
+			fileList.add(file);
+		}
+	}
+
+	@Override
+	public List<RepositoryFile> loadProject(String companyId) {
+		List<RepositoryFile> projects=new ArrayList<RepositoryFile>();
+		try{
+			Node rootNode=getRootNode();
+			NodeIterator nodeIterator = rootNode.getNodes();
+			while (nodeIterator.hasNext()) {
+				Node projectNode = nodeIterator.nextNode();
+				if (!projectNode.hasProperty(FILE)) {
+					continue;
+				}
+				if(StringUtils.isNotEmpty(companyId)){
+					if(projectNode.hasProperty(COMPANY_ID)){
+						String id=projectNode.getProperty(COMPANY_ID).getString();
+						if(!companyId.equals(id)){
+							continue;
+						}
+					}
+				}
+				if(projectNode.getName().indexOf(RESOURCE_SECURITY_CONFIG_FILE)>-1){
+					continue;
+				}
+				RepositoryFile projectFile = new RepositoryFile();
+				projectFile.setType(Type.project);
+				projectFile.setName(projectNode.getName());
+				projectFile.setFullPath("/" + projectNode.getName());
+				projects.add(projectFile);
+			}
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+		return projects;
+	}
+	
+	@Override
+	public Repository loadRepository(String project,String companyId,boolean classify,FileType[] types,String searchFileName) {
+		if(project!=null && project.startsWith("/")){
+			project=project.substring(1,project.length());
+		}
+		try {
+			Repository repo=new Repository();
+			List<String> projectNames=new ArrayList<String>();
+			repo.setProjectNames(projectNames);
+			RepositoryFile rootFile = new RepositoryFile();
+			rootFile.setFullPath("/");
+			rootFile.setName("项目列表");
+			rootFile.setType(Type.root);
+			Node rootNode=getRootNode();
+			NodeIterator nodeIterator = rootNode.getNodes();
+			while (nodeIterator.hasNext()) {
+				Node projectNode = nodeIterator.nextNode();
+				if (!projectNode.hasProperty(FILE)) {
+					continue;
+				}
+				if(StringUtils.isNotEmpty(companyId)){
+					if(projectNode.hasProperty(COMPANY_ID)){
+						String id=projectNode.getProperty(COMPANY_ID).getString();
+						if(!companyId.equals(id)){
+							continue;
+						}
+					}
+				}
+				String projectName = projectNode.getName();
+				if(projectName.indexOf(RESOURCE_SECURITY_CONFIG_FILE)>-1){
+					continue;
+				}
+				if (StringUtils.isNotBlank(project) && !project.equals(projectName)) {
+					continue;
+				}
+				if(!permissionService.projectHasPermission(projectNode.getPath())){
+					continue;
+				}
+				if(StringUtils.isBlank(project)){
+					projectNames.add(projectName);
+				}
+				RepositoryFile projectFile=buildProjectFile(projectNode,types,classify,searchFileName);
+				rootFile.addChild(projectFile, false);
+			}
+			repo.setRootFile(rootFile);
+			return repo;
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+	
+	private RepositoryFile buildProjectFile(Node projectNode,FileType[] types,boolean classify,String searchFileName) throws Exception{
+		RepositoryFile projectFile = new RepositoryFile();
+		projectFile.setType(Type.project);
+		projectFile.setName(projectNode.getName());
+		projectFile.setFullPath("/" + projectNode.getName());
+		RepositoryFile resDir = new RepositoryFile();
+		resDir.setFullPath(projectFile.getFullPath());
+		resDir.setName("资源");
+		if((types==null || types.length==0) && permissionService.projectPackageHasReadPermission(projectNode.getPath())){
+			RepositoryFile packageFile = new RepositoryFile();
+			packageFile.setName("知识包");
+			packageFile.setType(Type.resourcePackage);
+			packageFile.setFullPath(projectFile.getFullPath());
+			projectFile.addChild(packageFile, false);
+		}
+		if(classify){
+			resDir.setType(Type.resource);
+			createResourceCategory(projectNode, resDir,types,searchFileName);			
+		}else{
+			resDir.setType(Type.all);
+			buildResources(projectNode, resDir, types,searchFileName);
+		}
+		projectFile.addChild(resDir, false);
+		return projectFile;
+	}
+	
+	private void buildResources(Node projectNode, RepositoryFile libDir,FileType[] types,String searchFileName) throws Exception{
+		FileType[] fileTypes=types;
+		if(types==null || types.length==0){
+			fileTypes = new FileType[] { FileType.VariableLibrary,
+					FileType.ParameterLibrary, FileType.ConstantLibrary,
+					FileType.ActionLibrary, FileType.Ruleset,
+					FileType.RuleFlow, FileType.DecisionTable,
+					FileType.DecisionTree, FileType.ScriptDecisionTable,
+					FileType.UL,FileType.Scorecard };			
+		}
+		libDir.setLibType(LibType.all);
+		buildNodes(projectNode.getNodes(), libDir, fileTypes,Type.all,searchFileName);
+	}
+
+	private void createResourceCategory(Node projectNode, RepositoryFile libDir,FileType[] types,String searchFileName) throws Exception{
+		RepositoryFile subLib = buildLibFile(libDir,"库",LibType.res);
+		subLib.setType(Type.lib);
+		libDir.addChild(subLib, false);
+		FileType[] librarySubTypes = types;
+		if(types==null || types.length==0){
+			librarySubTypes=new FileType[] { FileType.VariableLibrary, FileType.ParameterLibrary,FileType.ConstantLibrary, FileType.ActionLibrary };
+		}
+		buildNodes(projectNode.getNodes(), subLib, librarySubTypes,Type.lib,searchFileName);
+		
+		RepositoryFile rulesLib = buildLibFile(libDir,"决策集",LibType.ruleset);
+		rulesLib.setFullPath(libDir.getFullPath());
+		rulesLib.setType(Type.ruleLib);
+		
+		RepositoryFile decisionTableLib = buildLibFile(libDir,"决策表",LibType.decisiontable);
+		decisionTableLib.setFullPath(libDir.getFullPath());
+		decisionTableLib.setType(Type.decisionTableLib);
+		
+		RepositoryFile decisionTreeLib = buildLibFile(libDir,"决策树",LibType.decisiontree);
+		decisionTreeLib.setFullPath(libDir.getFullPath());
+		decisionTreeLib.setType(Type.decisionTreeLib);
+		
+		RepositoryFile scorecardLib = buildLibFile(libDir,"评分卡",LibType.scorecard);
+		scorecardLib.setFullPath(libDir.getFullPath());
+		scorecardLib.setType(Type.scorecardLib);
+		
+		RepositoryFile flowLib = buildLibFile(libDir,"决策流",LibType.ruleflow);
+		flowLib.setFullPath(libDir.getFullPath());
+		flowLib.setType(Type.flowLib);
+		
+		libDir.addChild(rulesLib, false);
+		libDir.addChild(decisionTableLib, false);
+		libDir.addChild(decisionTreeLib, false);
+		libDir.addChild(scorecardLib, false);
+		libDir.addChild(flowLib, false);
+		
+		FileType[] libraryRuleTypes = types;
+		if(types==null || types.length==0){
+			libraryRuleTypes=new FileType[] { FileType.Ruleset, FileType.UL };
+		}
+		
+		FileType[] libraryDecisionTypes = types;
+		if(types==null || types.length==0){
+			libraryDecisionTypes = new FileType[] { FileType.DecisionTable, FileType.ScriptDecisionTable };
+		}
+		FileType[] libraryDecisionTreeTypes = types;
+		if(types==null || types.length==0){
+			libraryDecisionTreeTypes = new FileType[] { FileType.DecisionTree };
+		}
+		
+		FileType[] libraryFlowTypes = types;
+		if(types==null || types.length==0){
+			libraryFlowTypes = new FileType[] { FileType.RuleFlow };
+		}
+		
+		FileType[] libraryScorecardTypes = types;
+		if(types==null || types.length==0){
+			libraryScorecardTypes = new FileType[] { FileType.Scorecard };
+		}
+		
+		buildNodes(projectNode.getNodes(), rulesLib, libraryRuleTypes,Type.ruleLib,searchFileName);
+		buildNodes(projectNode.getNodes(), decisionTableLib, libraryDecisionTypes,Type.decisionTableLib,searchFileName);
+		buildNodes(projectNode.getNodes(), decisionTreeLib, libraryDecisionTreeTypes,Type.decisionTreeLib,searchFileName);
+		buildNodes(projectNode.getNodes(), scorecardLib, libraryScorecardTypes,Type.scorecardLib,searchFileName);
+		buildNodes(projectNode.getNodes(), flowLib, libraryFlowTypes,Type.flowLib,searchFileName);
+	}
+
+	private RepositoryFile buildLibFile(RepositoryFile libraryDir,String name,LibType libType) {
+		RepositoryFile subLib = new RepositoryFile();
+		subLib.setFullPath(libraryDir.getFullPath());
+		subLib.setName(name);
+		subLib.setLibType(libType);
+		return subLib;
+	}
+
+	private void buildNodes(NodeIterator nodeIterator, RepositoryFile parent, FileType[] types,Type folderType,String searchFileName) {
+		LibType libType=parent.getLibType();
+		try {
+			while (nodeIterator.hasNext()) {
+				Node fileNode = nodeIterator.nextNode();
+				if (!fileNode.hasProperty(FILE)) {
+					continue;
+				}
+				RepositoryFile file = new RepositoryFile();
+				file.setLibType(libType);
+				String name = fileNode.getName();
+				if (name.toLowerCase().indexOf(RES_PACKGE_FILE) > -1 || name.toLowerCase().indexOf(CLIENT_CONFIG_FILE) > -1 || name.toLowerCase().indexOf(RESOURCE_SECURITY_CONFIG_FILE) > -1) {
+					continue;
+				}
+				if (!fileNode.hasProperty(DIR_TAG)) {
+					
+					if(!permissionService.fileHasReadPermission(fileNode.getPath())){
+						continue;
+					}
+					
+					FileType fileType=null;
+					boolean add = false;
+					for (FileType type : types) {
+						if (name.toLowerCase().endsWith(type.toString())) {
+							fileType=type;
+							add = true;
+							break;
+						}
+					}
+					if (!add) {
+						continue;
+					}
+					
+					if(libType.equals(LibType.res)){
+						if(!fileType.equals(FileType.ActionLibrary) && !fileType.equals(FileType.ParameterLibrary) && !fileType.equals(FileType.ConstantLibrary) && !fileType.equals(FileType.VariableLibrary)) {
+							continue;
+						}
+					}
+					
+					if(libType.equals(LibType.decisiontable)){
+						if(!fileType.equals(FileType.ScriptDecisionTable) && !fileType.equals(FileType.DecisionTable)) {
+							continue;
+						}
+					}
+					
+					if(libType.equals(LibType.decisiontree)){
+						if(!fileType.equals(FileType.DecisionTree)) {
+							continue;
+						}
+					}
+					
+					if(libType.equals(LibType.ruleflow)){
+						if(!fileType.equals(FileType.RuleFlow)) {
+							continue;
+						}
+					}
+					
+					if(libType.equals(LibType.scorecard)){
+						if(!fileType.equals(FileType.Scorecard)) {
+							continue;
+						}
+					}
+					
+					if(libType.equals(LibType.ruleset)){
+						if(!fileType.equals(FileType.Ruleset) && !fileType.equals(FileType.UL)) {
+							continue;
+						}
+					}
+					if(StringUtils.isNotBlank(searchFileName)){
+						if(name.toLowerCase().indexOf(searchFileName.toLowerCase())==-1){
+							continue;
+						}
+					}
+					if (name.toLowerCase().endsWith(FileType.ActionLibrary.toString())) {
+						file.setType(Type.action);
+					} else if (name.toLowerCase().endsWith(FileType.VariableLibrary.toString())) {
+						file.setType(Type.variable);
+					} else if (name.toLowerCase().endsWith(FileType.ConstantLibrary.toString())) {
+						file.setType(Type.constant);
+					} else if (name.toLowerCase().endsWith(FileType.Ruleset.toString())) {
+						file.setType(Type.rule);
+					} else if (name.toLowerCase().endsWith(FileType.DecisionTable.toString())) {
+						file.setType(Type.decisionTable);
+					} else if (name.toLowerCase().endsWith(FileType.UL.toString())) {
+						file.setType(Type.ul);
+					} else if (name.toLowerCase().endsWith(FileType.ParameterLibrary.toString())) {
+						file.setType(Type.parameter);
+					} else if (name.toLowerCase().endsWith(FileType.RuleFlow.toString())) {
+						file.setType(Type.flow);
+					} else if (name.toLowerCase().endsWith(FileType.ScriptDecisionTable.toString())) {
+						file.setType(Type.scriptDecisionTable);
+					} else if (name.toLowerCase().endsWith(FileType.DecisionTree.toString())) {
+						file.setType(Type.decisionTree);
+					} else if (name.toLowerCase().endsWith(FileType.Scorecard.toString())) {
+						file.setType(Type.scorecard);
+					}
+					file.setFullPath(fileNode.getPath());
+					file.setName(name);
+					parent.addChild(file, false);
+					buildNodes(fileNode.getNodes(), file, types,folderType,searchFileName);
+				}else{
+					file.setFullPath(fileNode.getPath());
+					file.setName(name);
+					file.setType(Type.folder);
+					file.setFolderType(folderType);
+					parent.addChild(file, true);
+					buildNodes(fileNode.getNodes(), file, types,folderType,searchFileName);
+				}
+			}
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+
+	public void deleteFile(String path) {
+		if(!permissionService.fileHasWritePermission(path)){
+			throw new NoPermissionException();
+		}
+		
+		repositoryInteceptor.deleteFile(path);
+		path = processPath(path);
+		try {
+			Node rootNode=getRootNode();
+			if (!rootNode.hasNode(path)) {
+				throw new RuleException("File [" + path + "] not exist.");
+			}
+			String[] subpaths = path.split("/");
+			Node fileNode = rootNode;
+			for (String subpath : subpaths) {
+				if (StringUtils.isEmpty(subpath)) {
+					continue;
+				}
+				String subDirs[] = subpath.split("\\.");
+				for (String dir : subDirs) {
+					if (StringUtils.isEmpty(dir)) {
+						continue;
+					}
+					if (!fileNode.hasNode(dir)) {
+						continue;
+					}
+					fileNode = fileNode.getNode(dir);
+					if (!fileNode.isCheckedOut()) {
+						versionManager.checkout(fileNode.getPath());
+					}
+				}
+			}
+			fileNode = rootNode.getNode(path);
+			if (!fileNode.isCheckedOut()) {
+				versionManager.checkout(fileNode.getPath());
+			}
+			fileNode.remove();
+			session.save();
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+
+	@Override
+	public void saveFile(String path, String content,String createUser,boolean newVersion,String versionComment) {
+		path=Utils.decodeURL(path); 
+		if(path.indexOf(RES_PACKGE_FILE)>-1){
+			if(!permissionService.projectPackageHasWritePermission(path)){
+				throw new NoPermissionException();
+			}
+		}
+		if(!permissionService.fileHasWritePermission(path)){
+			throw new NoPermissionException();
+		}
+		
+		repositoryInteceptor.saveFile(path, content);
+		path = processPath(path);
+		int pos=path.indexOf(":");
+		if(pos!=-1){
+			path=path.substring(0,pos);
+		}
+		try {
+			Node rootNode=getRootNode();
+			if (!rootNode.hasNode(path)) {
+				throw new RuleException("File [" + path + "] not exist.");
+			}
+			Node fileNode = rootNode.getNode(path);
+			versionManager.checkout(fileNode.getPath());
+			Binary fileBinary = new BinaryImpl(content.getBytes("utf-8"));
+			fileNode.setProperty(DATA, fileBinary);
+			fileNode.setProperty(FILE, true);
+			fileNode.setProperty(CRATE_USER, createUser);
+			Calendar calendar = Calendar.getInstance();
+			calendar.setTime(new Date());
+			DateValue dateValue = new DateValue(calendar);
+			fileNode.setProperty(CRATE_DATE, dateValue);
+			if (newVersion && StringUtils.isNotBlank(versionComment)) {
+				fileNode.setProperty(VERSION_COMMENT, versionComment);
+			}
+			session.save();
+			if (newVersion) {
+				if(StringUtils.isNotBlank(versionComment)){
+					
+				}
+				versionManager.checkin(fileNode.getPath());
+			}
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+
+	public List<String> getReferenceFiles(String path) {
+		Node rootNode=getRootNode();
+		return refactor.getReferenceFiles(rootNode, path);
+	}
+	
+	@Override
+	public boolean fileExistCheck(String filePath) {
+		Node rootNode=getRootNode();
+		try{
+			filePath=processPath(filePath);
+			if(filePath.contains(" ") || filePath.equals("")){
+				return true;
+			}
+			if(rootNode.hasNode(filePath)){
+				return true;
+			}
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+		return false;
+	}
+	
+	@Override
+	public RepositoryFile createProject(String projectName, User user,boolean classify) {
+		if(!permissionService.isAdmin()){
+			throw new NoPermissionException();
+		}
+		
+		repositoryInteceptor.createProject(projectName);
+		Node rootNode=getRootNode();
+		try{
+			if(rootNode.hasNode(projectName)){
+				throw new RuleException("Project ["+projectName+"] already exist.");
+			}
+			Node projectNode=rootNode.addNode(projectName);
+			projectNode.addMixin("mix:versionable");
+			projectNode.setProperty(FILE, true);
+			projectNode.setProperty(CRATE_USER,user.getUsername());
+			projectNode.setProperty(COMPANY_ID, user.getCompanyId());
+			Calendar calendar = Calendar.getInstance();
+			calendar.setTime(new Date());
+			DateValue dateValue = new DateValue(calendar);
+			projectNode.setProperty(CRATE_DATE, dateValue);
+			session.save();
+			RepositoryFile projectFileInfo=buildProjectFile(projectNode, null ,classify,null);
+			return projectFileInfo;
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+
+	public void createDir(String path,User user) {
+		if(!permissionService.isAdmin()){
+			throw new NoPermissionException();
+		}
+		
+		repositoryInteceptor.createDir(path);
+		Node rootNode=getRootNode();
+		path = processPath(path);
+		try {
+			if (rootNode.hasNode(path)) {
+				throw new RuleException("Dir [" + path + "] already exist.");
+			}
+			boolean add = false;
+			String[] subpaths = path.split("/");
+			Node parentNode = rootNode;
+			for (String subpath : subpaths) {
+				if (StringUtils.isEmpty(subpath)) {
+					continue;
+				}
+				String subDirs[] = subpath.split("\\.");
+				for (String dir : subDirs) {
+					if (StringUtils.isEmpty(dir)) {
+						continue;
+					}
+					if (parentNode.hasNode(dir)) {
+						parentNode = parentNode.getNode(dir);
+					} else {
+						parentNode = parentNode.addNode(dir);
+						parentNode.addMixin("mix:versionable");
+						parentNode.setProperty(DIR_TAG, true);
+						parentNode.setProperty(FILE, true);
+						parentNode.setProperty(CRATE_USER,user.getUsername());
+						Calendar calendar = Calendar.getInstance();
+						calendar.setTime(new Date());
+						DateValue dateValue = new DateValue(calendar);
+						parentNode.setProperty(CRATE_DATE, dateValue);
+						add = true;
+					}
+				}
+			}
+			if (add) {
+				session.save();
+			}
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+
+	public void createFile(String path, String content,String createUser) {
+		if(!permissionService.isAdmin()){
+			throw new NoPermissionException();
+		}
+		createFileNode(path, content, createUser, true);
+	}
+	
+	
+	private void createFileNode(String path, String content,String createUser,boolean isFile){
+		repositoryInteceptor.createFile(path,content);
+		Node rootNode=getRootNode();
+		path = processPath(path);
+		try {
+			if (rootNode.hasNode(path)) {
+				throw new RuleException("File [" + path + "] already exist.");
+			}
+			Node fileNode = rootNode.addNode(path);
+			fileNode.addMixin("mix:versionable");
+			Binary fileBinary = new BinaryImpl(content.getBytes());
+			fileNode.setProperty(DATA, fileBinary);
+			if(isFile){
+				fileNode.setProperty(FILE, true);				
+			}
+			fileNode.setProperty(CRATE_USER, createUser);
+			Calendar calendar = Calendar.getInstance();
+			calendar.setTime(new Date());
+			DateValue dateValue = new DateValue(calendar);
+			fileNode.setProperty(CRATE_DATE, dateValue);
+			session.save();
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+	
+	public List<ResourcePackage> loadProjectResourcePackages(String project) throws Exception {
+		Node rootNode=getRootNode();
+		String filePath = processPath(project) + "/" + RES_PACKGE_FILE;
+		if (!rootNode.hasNode(filePath)) {
+			createFile(filePath, "<?xml version=\"1.0\" encoding=\"utf-8\"?><res-packages></res-packages>",null);
+			return null;
+		}
+		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		Node fileNode = rootNode.getNode(filePath);
+		Property property = fileNode.getProperty(DATA);
+		Binary fileBinary = property.getBinary();
+		InputStream inputStream = fileBinary.getStream();
+		String content = IOUtils.toString(inputStream, "utf-8");
+		inputStream.close();
+		Document document = DocumentHelper.parseText(content);
+		Element rootElement = document.getRootElement();
+		List<ResourcePackage> packages = new ArrayList<ResourcePackage>();
+		for (Object obj : rootElement.elements()) {
+			if (!(obj instanceof Element)) {
+				continue;
+			}
+			Element element = (Element) obj;
+			if (!element.getName().equals("res-package")) {
+				continue;
+			}
+			ResourcePackage p = new ResourcePackage();
+			String dateStr = element.attributeValue("create_date");
+			if (dateStr != null) {
+				p.setCreateDate(sd.parse(dateStr));
+			}
+			p.setId(element.attributeValue("id"));
+			p.setName(element.attributeValue("name"));
+			p.setProject(project);
+			List<ResourceItem> items = new ArrayList<ResourceItem>();
+			for (Object o : element.elements()) {
+				if (!(o instanceof Element)) {
+					continue;
+				}
+				Element ele = (Element) o;
+				if (!ele.getName().equals("res-package-item")) {
+					continue;
+				}
+				ResourceItem item = new ResourceItem();
+				item.setName(ele.attributeValue("name"));
+				item.setPackageId(p.getId());
+				item.setPath(ele.attributeValue("path"));
+				item.setVersion(ele.attributeValue("version"));
+				items.add(item);
+			}
+			p.setResourceItems(items);
+			packages.add(p);
+		}
+		return packages;
+	}
+
+	private InputStream readVersionFile(String path, String version) {
+		path = processPath(path);
+		try {
+			Node rootNode=getRootNode();
+			if (!rootNode.hasNode(path)) {
+				throw new RuleException("File [" + path + "] not exist.");
+			}
+			Node fileNode = rootNode.getNode(path);
+			VersionHistory versionHistory = versionManager.getVersionHistory(fileNode.getPath());
+			Version v = versionHistory.getVersion(version);
+			Node fnode = v.getFrozenNode();
+			Property property = fnode.getProperty(DATA);
+			Binary fileBinary = property.getBinary();
+			return fileBinary.getStream();
+		} catch (Exception ex) {
+			ex.printStackTrace();
+			throw new RuleException(ex);
+		} finally {
+		}
+	}
+
+	@Override
+	public InputStream readFile(String path,String version) {
+		if(!permissionService.fileHasReadPermission(path)){
+			throw new NoPermissionException();
+		}
+		
+		if(StringUtils.isNotBlank(version)){
+			repositoryInteceptor.readFile(path+":"+version);
+			return readVersionFile(path, version);
+		}
+		repositoryInteceptor.readFile(path);
+		Node rootNode=getRootNode();
+		int colonPos = path.lastIndexOf(":");
+		if (colonPos > -1) {
+			version = path.substring(colonPos + 1, path.length());
+			path = path.substring(0, colonPos);
+			return readFile(path, version);
+		}
+		path = processPath(path);
+		try {
+			if (!rootNode.hasNode(path)) {
+				throw new RuleException("File [" + path + "] not exist.");
+			}
+			Node fileNode = rootNode.getNode(path);
+			Property property = fileNode.getProperty(DATA);
+			Binary fileBinary = property.getBinary();
+			return fileBinary.getStream();
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+	
+	public void setRepositoryBuilder(RepositoryBuilder repositoryBuilder) {
+		this.repositoryBuilder = repositoryBuilder;
+	}
+
+	
+	private Node getRootNode(){
+		try {
+			return session.getRootNode();
+		} catch (RepositoryException e) {
+			throw new RuleException(e);
+		}
+	}
+	
+	private String processPath(String path) {
+		if (path.startsWith("/")) {
+			return path.substring(1, path.length());
+		}
+		return path;
+	}
+
+	public void fileRename(String path, String newPath) {
+		if(!permissionService.isAdmin()){
+			throw new NoPermissionException();
+		}
+		
+		repositoryInteceptor.renameFile(path, newPath);
+		path = processPath(path);
+		newPath = processPath(newPath);
+		try {
+			Node rootNode=getRootNode();
+			if (!rootNode.hasNode(path)) {
+				throw new RuleException("File [" + path + "] not exist.");
+			}
+			session.getWorkspace().move("/" + path, "/" + newPath);
+			session.save();
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+	
+	public void exportXml(String projectPath, OutputStream outputStream) {
+		if(!permissionService.isAdmin()){
+			throw new NoPermissionException();
+		}
+		
+		try {
+			session.exportSystemView(projectPath, outputStream, false, false);
+		} catch (Exception e) {
+			throw new RuleException(e);
+		}
+	}
+
+	public void importXml(InputStream inputStream,boolean overwrite) {
+		if(!permissionService.isAdmin()){
+			throw new NoPermissionException();
+		}
+		
+		try {
+			Node rootNode=getRootNode();
+			if(overwrite){
+				session.importXML(rootNode.getPath(), inputStream,
+						ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);				
+			}else{
+				session.importXML(rootNode.getPath(), inputStream,
+						ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);				
+			}
+			session.save();
+		} catch (Exception e) {
+			throw new RuleException(e);
+		}
+	}
+	
+	public void setPermissionService(PermissionService permissionService) {
+		this.permissionService = permissionService;
+	}
+	
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		try {
+			repository = repositoryBuilder.getRepository();
+			SimpleCredentials cred = new SimpleCredentials("admin", "admin".toCharArray());
+			cred.setAttribute("AutoRefresh", true);
+			session = repository.login(cred, null);
+			versionManager = session.getWorkspace().getVersionManager();
+			Collection<ReferenceUpdater> updaters = applicationContext.getBeansOfType(ReferenceUpdater.class).values();
+			refactor = new RepositoryRefactor(this, updaters);
+			
+			Collection<RepositoryInteceptor> repositoryInteceptors=applicationContext.getBeansOfType(RepositoryInteceptor.class).values();
+			if(repositoryInteceptors.size()==0){
+				repositoryInteceptor=new DefaultRepositoryInteceptor();
+			}else{
+				repositoryInteceptor=repositoryInteceptors.iterator().next();
+			}
+		} catch (Exception ex) {
+			throw new RuleException(ex);
+		}
+	}
+}

+ 117 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/model/FileType.java

@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.model;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.dsl.Constant;
+
+/**
+ * @author Jacky.gao
+ * @since 20141224
+ */
+public enum FileType {
+	Ruleset{
+		@Override
+		public String toString() {
+			return "rs.xml";
+		}
+	},DecisionTable{
+		@Override
+		public String toString() {
+			return "dt.xml";
+		}
+	},ScriptDecisionTable{
+		@Override
+		public String toString() {
+			return "dts.xml";
+		}
+	},ActionLibrary{
+		@Override
+		public String toString() {
+			return "al.xml";
+		}
+	},VariableLibrary{
+		@Override
+		public String toString() {
+			return "vl.xml";
+		}
+	},ParameterLibrary{
+		@Override
+		public String toString() {
+			return "pl.xml";
+		}
+	},ConstantLibrary{
+		@Override
+		public String toString() {
+			return "cl.xml";
+		}
+	},RuleFlow{
+		@Override
+		public String toString() {
+			return "rl.xml";
+		}
+	},UL{
+		@Override
+		public String toString() {
+			return Constant.UL_SUFFIX;
+		}
+	},DecisionTree{
+		@Override
+		public String toString() {
+			return "dtree.xml";
+		}
+	},Scorecard{
+		@Override
+		public String toString() {
+			return "sc";
+		}
+	},DIR{
+		@Override
+		public String toString() {
+			return "DIR";
+		}
+	};
+	
+	public static FileType parse(String type){
+		if(type.equals("rs.xml")){
+			return FileType.Ruleset;
+		}else if(type.equals("dt.xml")){
+			return FileType.DecisionTable;
+		}else if(type.equals("dts.xml")){
+			return FileType.ScriptDecisionTable;
+		}else if(type.equals("al.xml")){
+			return FileType.ActionLibrary;
+		}else if(type.equals("vl.xml")){
+			return FileType.VariableLibrary;
+		}else if(type.equals("pl.xml")){
+			return FileType.ParameterLibrary;
+		}else if(type.equals("cl.xml")){
+			return FileType.ConstantLibrary;
+		}else if(type.equals("rl.xml")){
+			return FileType.RuleFlow;
+		}else if(type.equals("ul")){
+			return FileType.UL;
+		}else if(type.equals("dtree.xml")){
+			return FileType.DecisionTree;
+		}else if(type.equals("sc")){
+			return FileType.Scorecard;
+		}else if(type.equals("DIR")){
+			return FileType.DIR;
+		}else{
+			throw new RuleException("Unknow type:"+type);
+		}
+	}
+}

+ 23 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/model/LibType.java

@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.model;
+/**
+ * @author Jacky.gao
+ * @since 201633
+ */
+public enum LibType {
+	ruleset,decisiontable,decisiontree,ruleflow,scorecard,res,all;
+}

+ 37 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/model/PermissionType.java

@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.model;
+
+/**
+ * @author Jacky.gao
+ * @since 201557
+ */
+public enum PermissionType {
+	ProjectVisible, NewVar, NewParam, NewConst, NewAction, 
+	NewRule, NewDslRule, NewDecisionTable,NewDslDecisionTable,NewRuleFlow,NewDecisionTree,
+	
+	DelVar,DelParam,DelConst,DelAction,DelRule,DelDslRule,
+	DelDecisionTable,DelDslDecisionTable,DelRuleFlow,DelDecisionTree,
+	
+	ModVar,ModParam,ModConst,ModAction,ModRule,ModDslRule,
+	ModDecisionTable,ModDslDecisionTable,ModRuleFlow,ModDecisionTree,
+	
+	InsertRow, DelRow, InsertConditionCol, ModConditionCol, DelConditionCol,
+	InsertActionCol, ModActionCol, DelActionCol,
+	
+	InsertDslRow, DelDslRow, InsertDslConditionCol, ModDslConditionCol, DelDslConditionCol,
+	InsertDslActionCol, ModDslActionCol, DelDslActionCol
+}

+ 117 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/model/RepositoryFile.java

@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+/**
+ * @author Jacky.gao
+ * @since 20141224
+ */
+public class RepositoryFile {
+	private String id;
+	private String name;
+	private String fullPath;
+	private Type type;
+	private Type folderType;
+	@JsonIgnore
+	private LibType libType;
+	@JsonIgnore
+	private RepositoryFile parentFile;
+	private List<RepositoryFile> children;
+	public RepositoryFile() {
+		this.id=UUID.randomUUID().toString();
+	}
+	
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public RepositoryFile getParentFile() {
+		return parentFile;
+	}
+	public void setParentFile(RepositoryFile parentFile) {
+		this.parentFile = parentFile;
+	}
+	public LibType getLibType() {
+		return libType;
+	}
+	public void setLibType(LibType libType) {
+		this.libType = libType;
+	}
+	public List<RepositoryFile> getChildren() {
+		return children;
+	}
+	public void addChild(RepositoryFile fileInfo,boolean isdir) {
+		if(this.children==null){
+			this.children=new ArrayList<RepositoryFile>();
+		}
+		fileInfo.setParentFile(this);
+		if(isdir){
+			this.children.add(0,fileInfo);
+		}else{
+			this.children.add(fileInfo);
+		}
+	}
+	public void setChildren(List<RepositoryFile> children) {
+		this.children = children;
+	}
+	public String getFullPath(){
+		if(fullPath==null){
+			if(parentFile!=null){
+				fullPath=parentFile.getFullPath();
+			}else{
+				fullPath="";
+			}
+			if(fullPath.equals("/")){
+				fullPath="";
+			}
+			fullPath+="/"+name;
+		}
+		return fullPath;
+	}
+	public void setFullPath(String fullPath) {
+		this.fullPath = fullPath;
+	}
+	public Type getType() {
+		return type;
+	}
+	public void setType(Type type) {
+		this.type = type;
+	}
+
+	public Type getFolderType() {
+		return folderType;
+	}
+
+	public void setFolderType(Type folderType) {
+		this.folderType = folderType;
+	}
+}

+ 53 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/model/ResourceItem.java

@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.model;
+
+
+/**
+ * @author Jacky.gao
+ * @since 201517
+ */
+public class ResourceItem {
+	private String name;
+	private String path;
+	private String packageId;
+	private String version;
+	
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getPath() {
+		return path;
+	}
+	public void setPath(String path) {
+		this.path = path;
+	}
+	public String getPackageId() {
+		return packageId;
+	}
+	public void setPackageId(String packageId) {
+		this.packageId = packageId;
+	}
+	public String getVersion() {
+		return version;
+	}
+	public void setVersion(String version) {
+		this.version = version;
+	}
+}

+ 63 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/model/ResourcePackage.java

@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.model;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author Jacky.gao
+ * @since 201517
+ */
+
+public class ResourcePackage {
+
+	private String id;
+	private String name;
+	private String project;
+	private Date createDate;
+	private List<ResourceItem> resourceItems;
+	public String getId() {
+		return id;
+	}
+	public void setId(String id) {
+		this.id = id;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getProject() {
+		return project;
+	}
+	public void setProject(String project) {
+		this.project = project;
+	}
+	public Date getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(Date createDate) {
+		this.createDate = createDate;
+	}
+	public List<ResourceItem> getResourceItems() {
+		return resourceItems;
+	}
+	public void setResourceItems(List<ResourceItem> resourceItems) {
+		this.resourceItems = resourceItems;
+	}
+}

+ 24 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/model/Type.java

@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.model;
+
+/**
+ * @author Jacky.gao
+ * @since 2016526
+ */
+public enum Type {
+	root, project, resource, resourcePackage, lib, action, parameter, constant, variable, ruleLib, decisionTableLib, decisionTreeLib, scorecardLib,flowLib, scorecard,rule, ul, decisionTable, scriptDecisionTable, decisionTree, flow, all, folder;
+}

+ 62 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/model/VersionFile.java

@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.model;
+
+import java.util.Date;
+
+/**
+ * @author Jacky.gao
+ * @since 2015325
+ */
+public class VersionFile {
+	private String path;
+	private String createUser;
+	private String name;
+	private String comment;
+	private Date createDate;
+	
+	public String getPath() {
+		return path;
+	}
+	public void setPath(String path) {
+		this.path = path;
+	}
+	public String getCreateUser() {
+		return createUser;
+	}
+	public void setCreateUser(String createUser) {
+		this.createUser = createUser;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getComment() {
+		return comment;
+	}
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+	public Date getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(Date createDate) {
+		this.createDate = createDate;
+	}
+}

+ 31 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/permission/PermissionService.java

@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.permission;
+/**
+ * @author Jacky.gao
+ * @since 201691
+ */
+public interface PermissionService {
+	boolean isAdmin();
+	
+	boolean projectHasPermission(String path);
+	
+	boolean projectPackageHasReadPermission(String path);
+	boolean projectPackageHasWritePermission(String path);
+	
+	boolean fileHasWritePermission(String path);
+	boolean fileHasReadPermission(String path);
+}

+ 225 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/permission/PermissionServiceImpl.java

@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.permission;
+
+import java.util.List;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.console.EnvironmentUtils;
+import com.bstek.urule.console.User;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.repository.model.FileType;
+import com.bstek.urule.console.servlet.RequestHolder;
+import com.bstek.urule.console.servlet.permission.ProjectConfig;
+import com.bstek.urule.console.servlet.permission.UserPermission;
+
+/**
+ * @author Jacky.gao
+ * @since 201691
+ */
+public class PermissionServiceImpl implements PermissionStore,PermissionService {
+	private RepositoryService repositoryService;
+	
+	@Override
+	public boolean projectHasPermission(String path) {
+		if(isAdmin()){
+			return true;
+		}
+		path=processPath(path);
+		int slashPos=path.indexOf("/");
+		if(slashPos==-1){
+			slashPos=path.length();
+		}
+		String project=path.substring(0,slashPos);
+		ProjectConfig config=loadProjectPermission(project);
+		if(config==null){
+			return false;
+		}
+		return config.isReadProject();
+	}
+	
+	
+	@Override
+	public boolean projectPackageHasReadPermission(String path) {
+		return projectPackagePermission(path, 0);
+	}
+	@Override
+	public boolean projectPackageHasWritePermission(String path) {
+		return projectPackagePermission(path, 1);
+	}
+	
+	private boolean projectPackagePermission(String path,int type){
+		if(isAdmin()){
+			return true;
+		}
+		path=processPath(path);
+		int slashPos=path.indexOf("/");
+		if(slashPos==-1){
+			slashPos=path.length();
+		}
+		String project=path.substring(0,slashPos);
+		ProjectConfig config=loadProjectPermission(project);
+		if(config==null){
+			return false;
+		}
+		if(type==0){
+			return config.isReadPackage();
+		}else{
+			return config.isWritePackage();
+		}
+	}
+	
+	@Override
+	public boolean fileHasReadPermission(String path) {
+		return fileHasPermission(path, 0);
+	}
+	
+	@Override
+	public boolean fileHasWritePermission(String path) {
+		return fileHasPermission(path, 1);
+	}
+	
+	private boolean fileHasPermission(String path,int permissionType){
+		if(isAdmin()){
+			return true;
+		}
+		path=processPath(path);
+		int slashPos=path.indexOf("/");
+		if(slashPos==-1){
+			throw new RuleException("Invalid file ["+path+"] for permission check.");
+		}
+		String project=path.substring(0,slashPos);
+		int pointPos=path.indexOf(".");
+		if(pointPos==-1){
+			return true;
+		}
+		ProjectConfig config=loadProjectPermission(project);
+		if(config==null){
+			return false;
+		}
+		String extName=path.substring(pointPos+1,path.length());
+		FileType type=FileType.parse(extName);
+		switch(type){
+		case VariableLibrary:
+			if(permissionType==0){
+				return config.isReadVariableFile();	
+			}else{
+				return config.isWriteVariableFile();			
+			}
+		case ActionLibrary:
+			if(permissionType==0){
+				return config.isReadActionFile();	
+			}else{
+				return config.isWriteActionFile();			
+			}
+		case ConstantLibrary:
+			if(permissionType==0){
+				return config.isReadConstantFile();	
+			}else{
+				return config.isWriteConstantFile();			
+			}
+		case DecisionTable:
+			if(permissionType==0){
+				return config.isReadDecisionTableFile();
+			}else{
+				return config.isWriteDecisionTableFile();
+			}
+		case DecisionTree:
+			if(permissionType==0){
+				return config.isReadDecisionTreeFile();
+			}else{
+				return config.isWriteDecisionTreeFile();
+			}
+		case ParameterLibrary:
+			if(permissionType==0){
+				return config.isReadParameterFile();
+			}else{
+				return config.isWriteParameterFile();
+			}
+		case RuleFlow:
+			if(permissionType==0){
+				return config.isReadFlowFile();
+			}else{
+				return config.isWriteFlowFile();
+			}
+		case Ruleset:
+			if(permissionType==0){
+				return config.isReadRuleFile();
+			}else{
+				return config.isWriteRuleFile();
+			}
+		case ScriptDecisionTable:
+			if(permissionType==0){
+				return config.isReadDecisionTableFile();
+			}else{
+				return config.isWriteDecisionTableFile();
+			}
+		case UL:
+			if(permissionType==0){
+				return config.isReadRuleFile();
+			}else{
+				return config.isWriteRuleFile();
+			}
+		case Scorecard:
+			if(permissionType==0){
+				return config.isReadScorecardFile();
+			}else{
+				return config.isWriteScorecardFile();
+			}
+		case DIR:
+			return true;
+		}
+		return false;
+	}
+	
+	private String processPath(String path) {
+		if (path.startsWith("/")) {
+			return path.substring(1, path.length());
+		}
+		return path;
+	}
+	@Override
+	public boolean isAdmin(){
+		User user=EnvironmentUtils.getLoginUser(RequestHolder.newRequestContext());
+		return user.isAdmin();
+	}
+	private ProjectConfig loadProjectPermission(String project){
+		User user=EnvironmentUtils.getLoginUser(RequestHolder.newRequestContext());
+		String companyId=user.getCompanyId();
+		List<UserPermission> permissions=repositoryService.loadResourceSecurityConfigs(companyId);
+		ProjectConfig target=null;
+		for(UserPermission p:permissions){
+			if(p.getUsername().equals(user.getUsername())){
+				for(ProjectConfig pc:p.getProjectConfigs()){
+					if(pc.getProject().equals(project)){
+						target=pc;
+						break;
+					}
+				}
+				break;
+			}
+		}
+		return target;
+	}
+	@Override
+	public void refreshPermissionStore() {
+		//do nothing...
+	}
+
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+}

+ 23 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/permission/PermissionStore.java

@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.permission;
+/**
+ * @author Jacky.gao
+ * @since 201691
+ */
+public interface PermissionStore {
+	void refreshPermissionStore();
+}

+ 46 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/updater/AbstractReferenceUpdater.java

@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.updater;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.dom4j.Document;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+
+import com.bstek.urule.RuleException;
+
+/**
+ * @author Jacky.gao
+ * @since 201584
+ */
+public abstract class AbstractReferenceUpdater implements ReferenceUpdater {
+	protected String xmlToString(Document doc){
+		StringWriter stringWriter = new StringWriter();
+		OutputFormat xmlFormat = new OutputFormat();
+		xmlFormat.setEncoding("UTF-8");
+		XMLWriter xmlWriter = new XMLWriter(stringWriter, xmlFormat);
+		try {
+			xmlWriter.write(doc);
+			xmlWriter.close();
+			return stringWriter.toString();
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw new RuleException(e);
+		}
+	}
+}

+ 105 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/updater/DecisionTableReferenceUpdater.java

@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.updater;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.console.repository.model.FileType;
+
+/**
+ * @author Jacky.gao
+ * @since 201584
+ */
+public class DecisionTableReferenceUpdater extends AbstractReferenceUpdater {
+	public boolean contain(String path, String xml) {
+		try{
+			Document doc=DocumentHelper.parseText(xml);
+			Element element=doc.getRootElement();
+			for(Object obj:element.elements()){
+				if(!(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				String name=ele.getName();
+				boolean match=false;
+				if(name.equals("import-variable-library")){
+					match=true;
+				}else if(name.equals("import-constant-library")){
+					match=true;
+				}else if(name.equals("import-action-library")){
+					match=true;
+				}else if(name.equals("import-parameter-library")){
+					match=true;
+				}
+				if(!match){
+					continue;
+				}
+				String filePath=ele.attributeValue("path");
+				if(filePath.endsWith(path)){
+					return true;
+				}
+			}
+			return false;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+	public String update(String oldPath, String newPath, String xml) {
+		try{
+			boolean modify=false;
+			Document doc=DocumentHelper.parseText(xml);
+			Element element=doc.getRootElement();
+			for(Object obj:element.elements()){
+				if(!(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				String name=ele.getName();
+				boolean match=false;
+				if(name.equals("import-variable-library")){
+					match=true;
+				}else if(name.equals("import-constant-library")){
+					match=true;
+				}else if(name.equals("import-action-library")){
+					match=true;
+				}else if(name.equals("import-parameter-library")){
+					match=true;
+				}
+				if(!match){
+					continue;
+				}
+				String path=ele.attributeValue("path");
+				if(path.endsWith(oldPath)){
+					ele.addAttribute("path", newPath);
+					modify=true;
+				}
+			}
+			if(modify){
+				return xmlToString(doc);
+			}
+			return null;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+
+	public boolean support(String path) {
+		return path.endsWith(FileType.DecisionTable.toString());
+	}
+}

+ 105 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/updater/FlowDefinitionReferenceUpdater.java

@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.updater;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.console.repository.model.FileType;
+
+/**
+ * @author Jacky.gao
+ * @since 201584
+ */
+public class FlowDefinitionReferenceUpdater extends AbstractReferenceUpdater {
+	public boolean contain(String path, String xml) {
+		try{
+			Document doc=DocumentHelper.parseText(xml);
+			Element element=doc.getRootElement();
+			for(Object obj:element.elements()){
+				if(!(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				String name=ele.getName();
+				boolean match=false;
+				if(name.equals("import-variable-library")){
+					match=true;
+				}else if(name.equals("import-constant-library")){
+					match=true;
+				}else if(name.equals("import-action-library")){
+					match=true;
+				}else if(name.equals("import-parameter-library")){
+					match=true;
+				}
+				if(!match){
+					continue;
+				}
+				String filePath=ele.attributeValue("path");
+				if(filePath.endsWith(path)){
+					return true;
+				}
+			}
+			return false;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+	public String update(String oldPath, String newPath, String xml) {
+		try{
+			boolean modify=false;
+			Document doc=DocumentHelper.parseText(xml);
+			Element element=doc.getRootElement();
+			for(Object obj:element.elements()){
+				if(!(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				String name=ele.getName();
+				boolean match=false;
+				if(name.equals("import-variable-library")){
+					match=true;
+				}else if(name.equals("import-constant-library")){
+					match=true;
+				}else if(name.equals("import-action-library")){
+					match=true;
+				}else if(name.equals("import-parameter-library")){
+					match=true;
+				}
+				if(!match){
+					continue;
+				}
+				String path=ele.attributeValue("path");
+				if(path.endsWith(oldPath)){
+					ele.addAttribute("path", newPath);
+					modify=true;
+				}
+			}
+			if(modify){
+				return xmlToString(doc);
+			}
+			return null;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+
+	public boolean support(String path) {
+		return path.endsWith(FileType.RuleFlow.toString());
+	}
+}

+ 25 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/updater/ReferenceUpdater.java

@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.updater;
+/**
+ * @author Jacky.gao
+ * @since 201584
+ */
+public interface ReferenceUpdater {
+	boolean contain(String path,String xml);
+	String update(String path,String newPath,String xml);
+	boolean support(String path);
+}

+ 105 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/updater/RuleSetReferenceUpdater.java

@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.updater;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.console.repository.model.FileType;
+
+/**
+ * @author Jacky.gao
+ * @since 201584
+ */
+public class RuleSetReferenceUpdater extends AbstractReferenceUpdater {
+	public boolean contain(String path, String xml) {
+		try{
+			Document doc=DocumentHelper.parseText(xml);
+			Element element=doc.getRootElement();
+			for(Object obj:element.elements()){
+				if(!(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				String name=ele.getName();
+				boolean match=false;
+				if(name.equals("import-variable-library")){
+					match=true;
+				}else if(name.equals("import-constant-library")){
+					match=true;
+				}else if(name.equals("import-action-library")){
+					match=true;
+				}else if(name.equals("import-parameter-library")){
+					match=true;
+				}
+				if(!match){
+					continue;
+				}
+				String filePath=ele.attributeValue("path");
+				if(filePath.endsWith(path)){
+					return true;
+				}
+			}
+			return false;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+	public String update(String oldPath, String newPath, String xml) {
+		try{
+			boolean modify=false;
+			Document doc=DocumentHelper.parseText(xml);
+			Element element=doc.getRootElement();
+			for(Object obj:element.elements()){
+				if(!(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				String name=ele.getName();
+				boolean match=false;
+				if(name.equals("import-variable-library")){
+					match=true;
+				}else if(name.equals("import-constant-library")){
+					match=true;
+				}else if(name.equals("import-action-library")){
+					match=true;
+				}else if(name.equals("import-parameter-library")){
+					match=true;
+				}
+				if(!match){
+					continue;
+				}
+				String path=ele.attributeValue("path");
+				if(path.endsWith(oldPath)){
+					ele.addAttribute("path", newPath);
+					modify=true;
+				}
+			}
+			if(modify){
+				return xmlToString(doc);
+			}
+			return null;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+
+	public boolean support(String path) {
+		return path.endsWith(FileType.Ruleset.toString());
+	}
+}

+ 105 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/updater/ScriptDecisionTableReferenceUpdater.java

@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.updater;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.console.repository.model.FileType;
+
+/**
+ * @author Jacky.gao
+ * @since 201584
+ */
+public class ScriptDecisionTableReferenceUpdater extends AbstractReferenceUpdater {
+	public boolean contain(String path, String xml) {
+		try{
+			Document doc=DocumentHelper.parseText(xml);
+			Element element=doc.getRootElement();
+			for(Object obj:element.elements()){
+				if(!(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				String name=ele.getName();
+				boolean match=false;
+				if(name.equals("import-variable-library")){
+					match=true;
+				}else if(name.equals("import-constant-library")){
+					match=true;
+				}else if(name.equals("import-action-library")){
+					match=true;
+				}else if(name.equals("import-parameter-library")){
+					match=true;
+				}
+				if(!match){
+					continue;
+				}
+				String filePath=ele.attributeValue("path");
+				if(filePath.endsWith(path)){
+					return true;
+				}
+			}
+			return false;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+	public String update(String oldPath, String newPath, String xml) {
+		try{
+			boolean modify=false;
+			Document doc=DocumentHelper.parseText(xml);
+			Element element=doc.getRootElement();
+			for(Object obj:element.elements()){
+				if(!(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				String name=ele.getName();
+				boolean match=false;
+				if(name.equals("import-variable-library")){
+					match=true;
+				}else if(name.equals("import-constant-library")){
+					match=true;
+				}else if(name.equals("import-action-library")){
+					match=true;
+				}else if(name.equals("import-parameter-library")){
+					match=true;
+				}
+				if(!match){
+					continue;
+				}
+				String path=ele.attributeValue("path");
+				if(path.endsWith(oldPath)){
+					ele.addAttribute("path", newPath);
+					modify=true;
+				}
+			}
+			if(modify){
+				return xmlToString(doc);
+			}
+			return null;
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+
+	public boolean support(String path) {
+		return path.endsWith(FileType.ScriptDecisionTable.toString());
+	}
+}

+ 59 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/updater/ScriptRuleSetReferenceUpdater.java

@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.repository.updater;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.console.repository.model.FileType;
+import com.bstek.urule.dsl.DSLRuleSetBuilder;
+import com.bstek.urule.model.rule.Library;
+import com.bstek.urule.model.rule.RuleSet;
+
+/**
+ * @author Jacky.gao
+ * @since 201584
+ */
+public class ScriptRuleSetReferenceUpdater extends AbstractReferenceUpdater {
+	private DSLRuleSetBuilder builder;
+	public boolean contain(String path, String xml) {
+		try {
+			RuleSet rs=builder.build(xml);
+			List<Library> libs=rs.getLibraries();
+			if(libs!=null){
+				for(Library lib:libs){
+					String libpath=lib.getPath();
+					if(libpath.indexOf(path)!=-1){
+						return true;
+					}
+				}
+			}
+			return false;
+		} catch (IOException e) {
+			throw new RuleException(e);
+		}
+	}
+	public String update(String path, String newPath, String xml) {
+		return null;
+	}
+	public void setBuilder(DSLRuleSetBuilder builder) {
+		this.builder = builder;
+	}
+	public boolean support(String path) {
+		return path.endsWith(FileType.UL.toString());
+	}
+}

+ 23 - 0
urule-console/src/main/java/com/bstek/urule/console/repository/workspace_template.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2017 Bstek
+  
+  Licensed under the Apache License, Version 2.0 (the "License"); you may not
+  use this file except in compliance with the License.  You may obtain a copy
+  of the License at
+  
+    http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+  License for the specific language governing permissions and limitations under
+  the License.
+-->
+<Workspace>
+	<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+		<param name="path" value="${wsp.home}"/>
+	</FileSystem>
+	<PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
+	</PersistenceManager>
+</Workspace>

+ 53 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/BaseServletHandler.java

@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet;
+
+import java.lang.reflect.Method;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.bstek.urule.RuleException;
+
+
+/**
+ * @author Jacky.gao
+ * @since 201663
+ */
+public abstract class BaseServletHandler implements ServletHandler {
+	
+	protected void invokeMethod(String methodName,HttpServletRequest req,HttpServletResponse resp){
+		try{
+			Method method=this.getClass().getMethod(methodName, new Class<?>[]{HttpServletRequest.class,HttpServletResponse.class});			
+			method.invoke(this, new Object[]{req,resp});
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+	
+	protected String retriveMethod(HttpServletRequest req) throws ServletException{
+		String path=req.getContextPath()+URuleServlet.URL;
+		String uri=req.getRequestURI();
+		String targetUrl=uri.substring(path.length());
+		int slashPos=targetUrl.indexOf("/",1);
+		if(slashPos>-1){
+			String methodName=targetUrl.substring(slashPos+1).trim();
+			return methodName.length()>0 ? methodName : null;
+		}
+		return null;
+	}
+}

+ 58 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/RenderPageServletHandler.java

@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.log.NullLogChute;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import com.bstek.urule.Utils;
+
+
+/**
+ * @author Jacky.gao
+ * @since 201666
+ */
+public abstract class RenderPageServletHandler extends WriteJsonServletHandler implements ApplicationContextAware{
+	protected VelocityEngine ve;
+	protected ApplicationContext applicationContext;
+	protected String buildProjectNameFromFile(String file) {
+		String project=null;
+		if(StringUtils.isNotBlank(file)){
+			file=Utils.decodeURL(file);
+			if(file.startsWith("/")){
+				file=file.substring(1,file.length());
+				int pos=file.indexOf("/");
+				project=file.substring(0,pos);
+			}
+		}
+		return project;
+	}
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext=applicationContext;
+		ve = new VelocityEngine();
+		ve.setProperty(Velocity.RESOURCE_LOADER, "class");
+		ve.setProperty("class.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+		ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM,new NullLogChute());
+		ve.init();	
+	}
+}

+ 38 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/RequestContext.java

@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author Jacky.gao
+ * @since 2016525
+ */
+public class RequestContext {
+	private HttpServletRequest req;
+	private HttpServletResponse resp;
+	public RequestContext(HttpServletRequest req, HttpServletResponse resp) {
+		this.req=req;
+		this.resp=resp;
+	}
+	public HttpServletRequest getRequest() {
+		return req;
+	}
+	public HttpServletResponse getResponse() {
+		return resp;
+	}
+}

+ 45 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/RequestHolder.java

@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author Jacky.gao
+ * @since 201691
+ */
+public class RequestHolder {
+	private static ThreadLocal<HttpServletRequest> request=new ThreadLocal<HttpServletRequest>();
+	private static ThreadLocal<HttpServletResponse> response=new ThreadLocal<HttpServletResponse>();
+	public static void set(HttpServletRequest request,HttpServletResponse response) {
+		RequestHolder.request.set(request);
+		RequestHolder.response.set(response);
+	}
+	public static RequestContext newRequestContext(){
+		return new RequestContext(request.get(),response.get());
+	}
+	public static void reset(){
+		request.remove();
+		response.remove();
+	}
+	public static HttpServletRequest getRequest() {
+		return request.get();
+	}
+	public static HttpServletResponse getResponse() {
+		return response.get();
+	}
+}

+ 79 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/ResourceLoaderServletHandler.java

@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+/**
+ * @author Jacky.gao
+ * @since 201666
+ */
+public class ResourceLoaderServletHandler implements ServletHandler,ApplicationContextAware{
+	public static final String URL="/res";
+	private ApplicationContext applicationContext;
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String path=req.getContextPath()+URuleServlet.URL+URL;
+		String uri=req.getRequestURI();
+		String resPath=uri.substring(path.length()+1);
+		String p="classpath:"+resPath;
+		if(p.endsWith(".js")){
+			resp.setContentType("text/javascript");	
+		}else if(p.endsWith(".css")){
+			resp.setContentType("text/css");
+		}else if(p.endsWith(".png")){
+			resp.setContentType("image/png");
+		}else if(p.endsWith(".jpg")){
+			resp.setContentType("image/jpeg");
+		}else{
+			resp.setContentType("application/octet-stream");
+		}
+		InputStream input=applicationContext.getResource(p).getInputStream();
+		OutputStream output=resp.getOutputStream();
+		try{
+			IOUtils.copy(input, output);			
+		}finally{
+			if(input!=null){
+				input.close();
+			}
+			if(output!=null){
+				output.flush();
+				output.close();
+			}
+		}
+	}
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext=applicationContext;
+	}
+	
+	@Override
+	public String url() {
+		return URL;
+	}
+}

+ 31 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/ServletHandler.java

@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author Jacky.gao
+ * @since 2016523
+ */
+public interface ServletHandler {
+	void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
+	String url();
+}

+ 113 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/URuleServlet.java

@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import com.bstek.urule.console.exception.NoPermissionException;
+
+/**
+ * @author Jacky.gao
+ * @since 2016523
+ */
+public class URuleServlet extends HttpServlet{
+	private static final long serialVersionUID = -5067484267904906233L;
+	private Map<String,ServletHandler> handlerMap=new HashMap<String,ServletHandler>();
+	public static final String URL="/urule";
+	
+	@Override
+	public void init(ServletConfig config) throws ServletException {
+		super.init(config);
+		WebApplicationContext applicationContext=WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
+		Collection<ServletHandler> handlers=applicationContext.getBeansOfType(ServletHandler.class).values();
+		for(ServletHandler handler:handlers){
+			String url=handler.url();
+			if(handlerMap.containsKey(url)){
+				throw new RuntimeException("Handler ["+url+"] already exist.");
+			}
+			handlerMap.put(url, handler);
+		}
+	}
+	
+	@Override
+	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		RequestHolder.set(req, resp);
+		try{
+			String path=req.getContextPath()+URL;
+			String uri=req.getRequestURI();
+			String targetUrl=uri.substring(path.length());
+			if(targetUrl.length()<1){
+				resp.sendRedirect(req.getContextPath()+"/urule/frame");
+				return;
+			}
+			int slashPos=targetUrl.indexOf("/",1);
+			if(slashPos>-1){
+				targetUrl=targetUrl.substring(0,slashPos);
+			}
+			ServletHandler targetHandler=handlerMap.get(targetUrl);
+			if(targetHandler==null){
+				outContent(resp,"Handler ["+targetUrl+"] not exist.");
+				return;
+			}
+			targetHandler.execute(req, resp);
+		}catch(Exception ex){
+			Throwable e=getCause(ex);
+			if(e instanceof NoPermissionException){
+				resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+				PrintWriter pw=resp.getWriter();
+				pw.write("<h1>Permission denied!</h1>");
+				pw.close();
+			}else{
+				throw new ServletException(ex);				
+			}
+		}finally{
+			RequestHolder.reset();
+		}
+	}
+
+	private void outContent(HttpServletResponse resp,String msg) throws IOException {
+		resp.setContentType("text/html");
+		PrintWriter pw=resp.getWriter();
+		pw.write("<html>");
+		pw.write("<header><title>URule Console</title></header>");
+		pw.write("<body>");
+		pw.write(msg);
+		pw.write("</body>");
+		pw.write("</html>");
+		pw.flush();
+		pw.close();
+	}
+	
+	private Throwable getCause(Throwable e){
+		if(e.getCause()!=null){
+			return getCause(e.getCause());
+		}
+		return e;
+	}
+}

+ 52 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/WriteJsonServletHandler.java

@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+import com.bstek.urule.Configure;
+
+/**
+ * @author Jacky.gao
+ * @since 2016523
+ */
+public abstract class WriteJsonServletHandler extends BaseServletHandler{
+	protected void writeObjectToJson(HttpServletResponse resp,Object obj) throws ServletException, IOException{
+		resp.setHeader("Access-Control-Allow-Origin", "*");
+		resp.setContentType("text/json");
+		resp.setCharacterEncoding("UTF-8");
+		ObjectMapper mapper=new ObjectMapper();
+		mapper.setSerializationInclusion(Inclusion.NON_NULL);
+		mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,false);
+		mapper.setDateFormat(new SimpleDateFormat(Configure.getDateFormat()));
+		OutputStream out = resp.getOutputStream();
+		try {
+			mapper.writeValue(out, obj);
+		} finally {
+			out.flush();
+			out.close();
+		}
+	}
+}

+ 142 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/action/ActionServletHandler.java

@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.action;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.model.ExposeAction;
+import com.bstek.urule.model.library.Datatype;
+import com.bstek.urule.model.library.action.Method;
+import com.bstek.urule.model.library.action.Parameter;
+
+public class ActionServletHandler extends RenderPageServletHandler{
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/action-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	public void loadMethods(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String beanId=req.getParameter("beanId");
+		Object bean=applicationContext.getBean(beanId);
+		List<Method> list=new ArrayList<Method>();
+		java.lang.reflect.Method[] methods=bean.getClass().getMethods();
+		for(java.lang.reflect.Method m:methods){
+			ExposeAction action=m.getAnnotation(ExposeAction.class);
+			if(action==null){
+				continue;
+			}
+			String name=m.getName();
+			Method method=new Method();
+			method.setMethodName(name);
+			method.setName(action.value());
+			method.setParameters(buildParameters(m));
+			list.add(method);
+		}
+		writeObjectToJson(resp, list);
+	}
+	
+	private List<Parameter> buildParameters(java.lang.reflect.Method m){
+		List<Parameter> parameters=new ArrayList<Parameter>();
+		Class<?>[] classes=m.getParameterTypes();
+		for(int i=0;i<classes.length;i++){
+			Class<?> c=classes[i];
+			Parameter p=new Parameter();
+			p.setName("参数"+i);
+			p.setType(buildDatatype(c));
+			parameters.add(p);
+		}
+		return parameters;
+	}
+	
+	private Datatype buildDatatype(Class<?> clazz) {
+		if(clazz.equals(String.class)){
+			return Datatype.String;
+		}else if(clazz.equals(BigDecimal.class)){
+			return Datatype.BigDecimal;
+		}else if(clazz.equals(Boolean.class)){
+			return Datatype.Boolean;
+		}else if(clazz.equals(Boolean.class)){
+			return Datatype.Boolean;
+		}else if(clazz.equals(boolean.class)){
+			return Datatype.Boolean;
+		}else if(clazz.equals(Date.class)){
+			return Datatype.Date;
+		}else if(clazz.equals(Double.class)){
+			return Datatype.Double;
+		}else if(clazz.equals(double.class)){
+			return Datatype.Double;
+		}else if(Enum.class.isAssignableFrom(clazz)){
+			return Datatype.Enum;
+		}else if(clazz.equals(Float.class)){
+			return Datatype.Float;
+		}else if(clazz.equals(float.class)){
+			return Datatype.Float;
+		}else if(clazz.equals(Integer.class)){
+			return Datatype.Integer;
+		}else if(clazz.equals(int.class)){
+			return Datatype.Integer;
+		}else if(clazz.equals(Character.class)){
+			return Datatype.Char;
+		}else if(clazz.equals(char.class)){
+			return Datatype.Char;
+		}else if(List.class.isAssignableFrom(clazz)){
+			return Datatype.List;
+		}else if(clazz.equals(long.class)){
+			return Datatype.Long;
+		}else if(clazz.equals(Long.class)){
+			return Datatype.Long;
+		}else if(Map.class.isAssignableFrom(clazz)){
+			return Datatype.Map;
+		}else if(Set.class.isAssignableFrom(clazz)){
+			return Datatype.Set;
+		}else{
+			return Datatype.Object;
+		}
+	}	
+	
+	
+	@Override
+	public String url() {
+		return "/actioneditor";
+	}
+	
+}

+ 80 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/client/ClientConfigServletHandler.java

@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.client;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.EnvironmentUtils;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.repository.RepositoryServiceImpl;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.console.servlet.RequestContext;
+
+/**
+ * @author Jacky.gao
+ * @since 2016811
+ */
+public class ClientConfigServletHandler extends RenderPageServletHandler{
+	private RepositoryService repositoryService;
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/client-config-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	public void loadData(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String project=req.getParameter("project");
+		project=Utils.decodeURL(project);
+		writeObjectToJson(resp, repositoryService.loadClientConfigs(project));
+	}
+	public void save(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String project=req.getParameter("project");
+		project=Utils.decodeURL(project);
+		String file=project+"/"+RepositoryServiceImpl.CLIENT_CONFIG_FILE;
+		String content=req.getParameter("content");
+		String username=EnvironmentUtils.getLoginUser(new RequestContext(req, resp)).getUsername();
+		repositoryService.saveFile(file, content, username, false,null);
+	}
+	
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+	
+	@Override
+	public String url() {
+		return "/clientconfig";
+	}
+	
+}

+ 291 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/common/CommonServletHandler.java

@@ -0,0 +1,291 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.common;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.apache.commons.lang.StringUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.EnvironmentUtils;
+import com.bstek.urule.console.User;
+import com.bstek.urule.console.repository.Repository;
+import com.bstek.urule.console.repository.RepositoryResourceProvider;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.repository.model.FileType;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.console.servlet.RequestContext;
+import com.bstek.urule.dsl.RuleParserLexer;
+import com.bstek.urule.dsl.RuleParserParser;
+import com.bstek.urule.model.function.FunctionDescriptor;
+import com.bstek.urule.model.library.action.ActionLibrary;
+import com.bstek.urule.model.library.action.SpringBean;
+import com.bstek.urule.parse.deserializer.ActionLibraryDeserializer;
+import com.bstek.urule.parse.deserializer.ConstantLibraryDeserializer;
+import com.bstek.urule.parse.deserializer.DecisionTableDeserializer;
+import com.bstek.urule.parse.deserializer.DecisionTreeDeserializer;
+import com.bstek.urule.parse.deserializer.Deserializer;
+import com.bstek.urule.parse.deserializer.ParameterLibraryDeserializer;
+import com.bstek.urule.parse.deserializer.RuleSetDeserializer;
+import com.bstek.urule.parse.deserializer.ScorecardDeserializer;
+import com.bstek.urule.parse.deserializer.ScriptDecisionTableDeserializer;
+import com.bstek.urule.parse.deserializer.VariableLibraryDeserializer;
+import com.bstek.urule.runtime.BuiltInActionLibraryBuilder;
+
+/**
+ * @author Jacky.gao
+ * @since 2016725
+ */
+public class CommonServletHandler extends RenderPageServletHandler{
+	private RepositoryService repositoryService;
+	private BuiltInActionLibraryBuilder builtInActionLibraryBuilder;
+	private List<Deserializer<?>> deserializers=new ArrayList<Deserializer<?>>();
+	private List<FunctionDescriptor> functionDescriptors=new ArrayList<FunctionDescriptor>();
+	
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			throw new ServletException("Unsupport this operation.");
+		}
+	}
+	public void saveFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String file=req.getParameter("file");
+		String content=req.getParameter("content");
+		String versionComment=req.getParameter("versionComment");
+		Boolean newVersion = Boolean.valueOf(req.getParameter("newVersion"));
+		String createUser=EnvironmentUtils.getLoginUser(new RequestContext(req, resp)).getUsername();
+		repositoryService.saveFile(file,content,createUser,newVersion,versionComment);
+	}
+	public void loadReferenceFiles(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String path=req.getParameter("path");
+		List<String> files=repositoryService.getReferenceFiles(path);
+		List<RefFile> refFiles=new ArrayList<RefFile>();
+		for(String file:files){
+			RefFile ref=new RefFile();
+			refFiles.add(ref);
+			ref.setPath(file);
+			if(file.endsWith(FileType.Ruleset.toString())){
+				ref.setEditor("/ruleseteditor");
+				ref.setType("决策集");
+			}else if(file.endsWith(FileType.UL.toString())){
+				ref.setEditor("/uleditor");
+				ref.setType("脚本决策集");
+			}else if(file.endsWith(FileType.DecisionTable.toString())){
+				ref.setEditor("/decisiontableeditor");
+				ref.setType("决策表");
+			}else if(file.endsWith(FileType.ScriptDecisionTable.toString())){
+				ref.setEditor("/scriptdecisiontableeditor");
+				ref.setType("脚本决策表");
+			}else if(file.endsWith(FileType.DecisionTree.toString())){
+				ref.setEditor("/decisiontreeeditor");			
+				ref.setType("决策树");
+			}else if(file.endsWith(FileType.RuleFlow.toString())){
+				ref.setEditor("/ruleflowdesigner");			
+				ref.setType("决策流");
+			}
+			int pos=file.lastIndexOf("/");
+			String name=file;
+			if(pos>-1){
+				name=file.substring(pos+1,file.length());
+			}
+			ref.setName(name);
+		}
+		writeObjectToJson(resp, refFiles);
+	}
+	
+	public void loadResourceTreeData(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String project=req.getParameter("project");
+		project=Utils.decodeURL(project); 
+		String forLib=req.getParameter("forLib");
+		String fileType=req.getParameter("fileType");
+		String searchFileName=req.getParameter("searchFileName");
+		
+		User user=EnvironmentUtils.getLoginUser(new RequestContext(req,resp));
+		FileType[] types=null;
+		if(StringUtils.isNotBlank(forLib) && forLib.equals("true")){
+			types=new FileType[]{FileType.ActionLibrary,FileType.ConstantLibrary,FileType.VariableLibrary,FileType.ParameterLibrary};
+		}else if(StringUtils.isNotBlank(fileType)){
+			String[] fileTypes=fileType.split(",");
+			types=new FileType[fileTypes.length];
+			for(int i=0;i<fileTypes.length;i++){
+				types[i]=FileType.valueOf(fileTypes[i]);
+			}
+		}else{
+			types=new FileType[]{FileType.UL,FileType.Ruleset,FileType.RuleFlow,FileType.DecisionTable,FileType.ScriptDecisionTable,FileType.DecisionTree,FileType.Scorecard};
+		}
+		Repository repo=repositoryService.loadRepository(project,user.getCompanyId(),false,types,searchFileName);	
+		writeObjectToJson(resp, repo.getRootFile());
+	}
+	
+	public void loadFunctions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		writeObjectToJson(resp, functionDescriptors);
+	}
+	
+	public void scriptValidation(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String content=req.getParameter("content");
+		if(StringUtils.isNotBlank(content)){
+			ScriptType type=ScriptType.valueOf(req.getParameter("type"));
+			ANTLRInputStream antlrInputStream=new ANTLRInputStream(content);
+			RuleParserLexer lexer=new RuleParserLexer(antlrInputStream);
+			CommonTokenStream steam=new CommonTokenStream(lexer);
+			RuleParserParser parser=new RuleParserParser(steam);
+			parser.removeErrorListeners();
+			ScriptErrorListener errorListener=new ScriptErrorListener();
+			parser.addErrorListener(errorListener);
+			switch(type){
+			case Script:
+				parser.ruleSet();
+				break;
+			case DecisionNode:
+				parser.condition();
+				break;
+			case ScriptNode:
+				parser.actions();
+				
+			}
+			List<ErrorInfo> infos=errorListener.getInfos();
+			writeObjectToJson(resp, infos);
+		}
+	}
+	
+	
+	public void loadXml(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		List<Object> result=new ArrayList<Object>();
+		String files=req.getParameter("files");
+		files=Utils.decodeURL(files);
+		boolean isaction=false;
+		if(files!=null){
+			if(files.startsWith("builtinactions")){
+				isaction=true;
+			}else{
+				String[] paths=files.split(";");
+				for(String path:paths){
+					if(path.startsWith(RepositoryResourceProvider.JCR)){
+						path=path.substring(4,path.length());					
+					}
+					String[] subpaths=path.split(",");
+					path=subpaths[0];
+					String version=null;
+					if(subpaths.length==2){
+						version=subpaths[1];
+					}
+					InputStream inputStream=null;
+					if(StringUtils.isEmpty(version)){
+						inputStream=repositoryService.readFile(path,null);
+					}else{
+						inputStream=repositoryService.readFile(path,version);			
+					}
+					Element element=parseXml(inputStream);
+					for(Deserializer<?> des:deserializers){
+						if(des.support(element)){
+							result.add(des.deserialize(element));
+							if(des instanceof ActionLibraryDeserializer){
+								isaction=true;
+							}
+							break;
+						}
+					}
+					inputStream.close();
+				}
+			}
+		}
+		if(isaction){
+			List<SpringBean> beans=builtInActionLibraryBuilder.getBuiltInActions();
+			if(beans.size()>0){
+				ActionLibrary al=new ActionLibrary();
+				al.setSpringBeans(beans);
+				result.add(al);
+			}
+		}
+		writeObjectToJson(resp, result);
+	}
+	
+	protected Element parseXml(InputStream stream){
+		SAXReader reader=new SAXReader();
+		Document document;
+		try {
+			document = reader.read(stream);
+			Element root=document.getRootElement();
+			return root;
+		} catch (DocumentException e) {
+			throw new RuleException(e);
+		}
+	}
+	
+	public void setBuiltInActionLibraryBuilder(BuiltInActionLibraryBuilder builtInActionLibraryBuilder) {
+		this.builtInActionLibraryBuilder = builtInActionLibraryBuilder;
+	}
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+	
+	@Override
+	public String url() {
+		return "/common";
+	}
+	
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		super.setApplicationContext(applicationContext);
+		ActionLibraryDeserializer actionLibraryDeserializer=(ActionLibraryDeserializer)applicationContext.getBean(ActionLibraryDeserializer.BEAN_ID);
+		VariableLibraryDeserializer variableLibraryDeserializer=(VariableLibraryDeserializer)applicationContext.getBean(VariableLibraryDeserializer.BEAN_ID);
+		ConstantLibraryDeserializer constantLibraryDeserializer=(ConstantLibraryDeserializer)applicationContext.getBean(ConstantLibraryDeserializer.BEAN_ID);
+		RuleSetDeserializer ruleSetDeserializer=(RuleSetDeserializer)applicationContext.getBean(RuleSetDeserializer.BEAN_ID);
+		DecisionTableDeserializer decisionTableDeserializer=(DecisionTableDeserializer)applicationContext.getBean(DecisionTableDeserializer.BEAN_ID);
+		ScriptDecisionTableDeserializer scriptDecisionTableDeserializer=(ScriptDecisionTableDeserializer)applicationContext.getBean(ScriptDecisionTableDeserializer.BEAN_ID);
+		DecisionTreeDeserializer decisionTreeDeserializer=(DecisionTreeDeserializer)applicationContext.getBean(DecisionTreeDeserializer.BEAN_ID);
+		ScorecardDeserializer scorecardDeserializer=(ScorecardDeserializer)applicationContext.getBean(ScorecardDeserializer.BEAN_ID);
+
+		ParameterLibraryDeserializer parameterLibraryDeserializer=(ParameterLibraryDeserializer)applicationContext.getBean(ParameterLibraryDeserializer.BEAN_ID);
+		deserializers.add(actionLibraryDeserializer);
+		deserializers.add(variableLibraryDeserializer);
+		deserializers.add(constantLibraryDeserializer);
+		deserializers.add(ruleSetDeserializer);
+		deserializers.add(decisionTableDeserializer);
+		deserializers.add(scriptDecisionTableDeserializer);
+		deserializers.add(decisionTreeDeserializer);
+		deserializers.add(parameterLibraryDeserializer);
+		deserializers.add(scorecardDeserializer);
+		
+		Collection<FunctionDescriptor> coll=applicationContext.getBeansOfType(FunctionDescriptor.class).values();
+		for(FunctionDescriptor fun:coll){
+			if(fun.isDisabled()){
+				continue;
+			}
+			functionDescriptors.add(fun);
+		}
+	}
+}

+ 49 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/common/ErrorInfo.java

@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.common;
+/**
+ * @author Jacky.gao
+ * @since 2016726
+ */
+public class ErrorInfo {
+	private int line;
+	private int charPositionInLine;
+	private String message;
+	
+	public ErrorInfo(int line,int charPositionInLine,String message) {
+		this.line = line;
+		this.charPositionInLine=charPositionInLine;
+		this.message = message;
+	}
+	public int getLine() {
+		return line;
+	}
+	public void setLine(int line) {
+		this.line = line;
+	}
+	public String getMessage() {
+		return message;
+	}
+	public void setMessage(String message) {
+		this.message = message;
+	}
+	public int getCharPositionInLine() {
+		return charPositionInLine;
+	}
+	public void setCharPositionInLine(int charPositionInLine) {
+		this.charPositionInLine = charPositionInLine;
+	}
+}

+ 51 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/common/RefFile.java

@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.common;
+/**
+ * @author Jacky.gao
+ * @since 201689
+ */
+public class RefFile {
+	private String name;
+	private String path;
+	private String editor;
+	private String type;
+	
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getPath() {
+		return path;
+	}
+	public void setPath(String path) {
+		this.path = path;
+	}
+	public String getEditor() {
+		return editor;
+	}
+	public void setEditor(String editor) {
+		this.editor = editor;
+	}
+	public String getType() {
+		return type;
+	}
+	public void setType(String type) {
+		this.type = type;
+	}
+}

+ 38 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/common/ScriptErrorListener.java

@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+
+/**
+ * @author Jacky.gao
+ * @since 2016726
+ */
+public class ScriptErrorListener extends BaseErrorListener {
+	private List<ErrorInfo> infos=new ArrayList<ErrorInfo>();
+	@Override
+	public void syntaxError(Recognizer<?, ?> recognizer,Object offendingSymbol, int line, int charPositionInLine,String msg, RecognitionException e) {
+		infos.add(new ErrorInfo(line,charPositionInLine,msg));
+	}
+	public List<ErrorInfo> getInfos() {
+		return infos;
+	}
+}

+ 23 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/common/ScriptType.java

@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.common;
+/**
+ * @author Jacky.gao
+ * @since 2016726
+ */
+public enum ScriptType {
+	DecisionNode,ScriptNode,Script;
+}

+ 52 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/constant/ConstantServletHandler.java

@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.constant;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+
+public class ConstantServletHandler extends RenderPageServletHandler{
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/constant-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	@Override
+	public String url() {
+		return "/constanteditor";
+	}
+	
+}

+ 60 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/decisiontable/DecisiontableEditorServletHandler.java

@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.decisiontable;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+
+/**
+ * @author Jacky.gao
+ * @since 201681
+ */
+public class DecisiontableEditorServletHandler extends RenderPageServletHandler{
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			String file=req.getParameter("file");
+			String project = buildProjectNameFromFile(file);
+			if(project!=null){
+				context.put("project", project);
+			}
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/decisiontable-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	@Override
+	public String url() {
+		return "/decisiontableeditor";
+	}
+}

+ 60 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/decisiontree/DecisionTreeEditorServletHandler.java

@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.decisiontree;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+
+/**
+ * @author Jacky.gao
+ * @since 201681
+ */
+public class DecisionTreeEditorServletHandler extends RenderPageServletHandler{
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			String file=req.getParameter("file");
+			String project = buildProjectNameFromFile(file);
+			if(project!=null){
+				context.put("project", project);
+			}
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/decisiontree-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	@Override
+	public String url() {
+		return "/decisiontreeeditor";
+	}
+}

+ 36 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/Box.java

@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.diagram;
+/**
+ * @author Jacky.gao
+ * @since 201532
+ */
+public class Box {
+	private int width;
+	private int height;
+	public int getWidth() {
+		return width;
+	}
+	public void setWidth(int width) {
+		this.width = width;
+	}
+	public int getHeight() {
+		return height;
+	}
+	public void setHeight(int height) {
+		this.height = height;
+	}
+}

+ 57 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/Diagram.java

@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.diagram;
+
+import java.util.List;
+
+/**
+ * @author Jacky.gao
+ * @since 201516
+ */
+public class Diagram {
+	private List<Edge> edges;
+	private NodeInfo rootNode;
+	private int width;
+	private int height;
+	public Diagram(List<Edge> edges, NodeInfo rootNode) {
+		this.edges = edges;
+		this.rootNode = rootNode;
+	}
+	public List<Edge> getEdges() {
+		return edges;
+	}
+	public void setEdges(List<Edge> edges) {
+		this.edges = edges;
+	}
+	public NodeInfo getRootNode() {
+		return rootNode;
+	}
+	public void setRootNode(NodeInfo rootNode) {
+		this.rootNode = rootNode;
+	}
+	public int getWidth() {
+		return width;
+	}
+	public void setWidth(int width) {
+		this.width = width;
+	}
+	public int getHeight() {
+		return height;
+	}
+	public void setHeight(int height) {
+		this.height = height;
+	}
+}

+ 52 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/DiagramContext.java

@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.diagram;
+
+import java.util.List;
+import java.util.Map;
+
+import com.bstek.urule.model.Node;
+
+/**
+ * @author Jacky.gao
+ * @since 201516
+ */
+public class DiagramContext {
+	private int id;
+	private List<Edge> edges;
+	private Map<Node,NodeInfo> nodeMap;
+	public DiagramContext(List<Edge> edges,Map<Node, NodeInfo> nodeMap) {
+		this.edges = edges;
+		this.nodeMap = nodeMap;
+	}
+
+	public List<Edge> getEdges() {
+		return edges;
+	}
+	public void addEdge(Edge edge) {
+		edges.add(edge);
+	}
+	public Map<Node, NodeInfo> getNodeMap() {
+		return nodeMap;
+	}
+	public void setNodeMap(Map<Node, NodeInfo> nodeMap) {
+		this.nodeMap = nodeMap;
+	}
+	public int nextId(){
+		id++;
+		return id;
+	}
+}

+ 40 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/Edge.java

@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.diagram;
+/**
+ * @author Jacky.gao
+ * @since 201516
+ */
+public class Edge {
+	private int from;
+	private int to;
+	public Edge(int from, int to) {
+		this.from = from;
+		this.to = to;
+	}
+	public int getFrom() {
+		return from;
+	}
+	public void setFrom(int from) {
+		this.from = from;
+	}
+	public int getTo() {
+		return to;
+	}
+	public void setTo(int to) {
+		this.to = to;
+	}
+}

+ 109 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/NodeInfo.java

@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.diagram;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+/**
+ * @author Jacky.gao
+ * @since 201516
+ */
+public class NodeInfo {
+	private int id;
+	@JsonIgnore
+	private int level;
+	private String label;
+	private String title;
+	private String color;
+	private int x;
+	private int y;
+	private int width;
+	private int height;
+	private int roundCorner;
+	private List<NodeInfo> children;
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public int getLevel() {
+		return level;
+	}
+	public void setLevel(int level) {
+		this.level = level;
+	}
+	public String getLabel() {
+		return label;
+	}
+	public void setLabel(String label) {
+		this.label = label;
+	}
+	public String getColor() {
+		return color;
+	}
+	public void setColor(String color) {
+		this.color = color;
+	}
+	public String getTitle() {
+		return title;
+	}
+	public void setTitle(String title) {
+		this.title = title;
+	}
+	public int getX() {
+		return x;
+	}
+	public void setX(int x) {
+		this.x = x;
+	}
+	public int getY() {
+		return y;
+	}
+	public void setY(int y) {
+		this.y = y;
+	}
+	public int getWidth() {
+		return width;
+	}
+	public void setWidth(int width) {
+		this.width = width;
+	}
+	public int getHeight() {
+		return height;
+	}
+	public void setHeight(int height) {
+		this.height = height;
+	}
+	public int getRoundCorner() {
+		return roundCorner;
+	}
+	public void setRoundCorner(int roundCorner) {
+		this.roundCorner = roundCorner;
+	}
+	public List<NodeInfo> getChildren() {
+		return children;
+	}
+	public void addChild(NodeInfo nodeInfo){
+		if(children==null){
+			children=new ArrayList<NodeInfo>();
+		}
+		children.add(nodeInfo);
+	}
+}

+ 219 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/ReteDiagramServletHandler.java

@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.diagram;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.Utils;
+import com.bstek.urule.builder.KnowledgeBase;
+import com.bstek.urule.builder.KnowledgeBuilder;
+import com.bstek.urule.builder.ResourceBase;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.console.servlet.respackage.HttpSessionKnowledgeCache;
+import com.bstek.urule.console.servlet.respackage.PackageServletHandler;
+import com.bstek.urule.model.Node;
+import com.bstek.urule.model.rete.AndNode;
+import com.bstek.urule.model.rete.CriteriaNode;
+import com.bstek.urule.model.rete.Line;
+import com.bstek.urule.model.rete.NamedCriteriaNode;
+import com.bstek.urule.model.rete.ObjectTypeNode;
+import com.bstek.urule.model.rete.OrNode;
+import com.bstek.urule.model.rete.Rete;
+import com.bstek.urule.model.rete.TerminalNode;
+
+/**
+ * @author Jacky.gao
+ * @since 2016623
+ */
+public class ReteDiagramServletHandler extends RenderPageServletHandler {
+	private KnowledgeBuilder knowledgeBuilder;
+	private ReteNodeLayout nodeLayout;
+	private final int nodeWidth=30;
+	private final int nodeHeight=30;
+	private HttpSessionKnowledgeCache httpSessionKnowledgeCache;
+	public ReteDiagramServletHandler() {
+		nodeLayout=new ReteNodeLayout();
+	}
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			context.put("files", req.getParameter("files"));
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/rete-diagram.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	public void loadReteDiagramData(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String files=req.getParameter("files");
+		files=Utils.decodeURL(files);
+		KnowledgeBase knowledgeBase=(KnowledgeBase)httpSessionKnowledgeCache.get(req,PackageServletHandler.KB_KEY);
+		if(knowledgeBase==null){
+			ResourceBase resourceBase=knowledgeBuilder.newResourceBase();
+			String[] paths=files.split(";");
+			for(String path:paths){
+				String[] subpaths=path.split(",");
+				path=subpaths[0];
+				String version=subpaths[1];
+				path=Utils.toUTF8(path);
+				resourceBase.addResource(path,version);
+			}
+			knowledgeBase=knowledgeBuilder.buildKnowledgeBase(resourceBase);
+			httpSessionKnowledgeCache.put(req,PackageServletHandler.KB_KEY, knowledgeBase);
+		}
+		Rete rete=knowledgeBase.getRete();
+		Diagram diagram=buildReteDiagram(rete);
+		writeObjectToJson(resp,diagram);
+	}
+
+	private Diagram buildReteDiagram(Rete rete){
+		Map<Node,NodeInfo> nodeMap=new HashMap<Node,NodeInfo>();
+		List<Edge> edges=new ArrayList<Edge>();
+		NodeInfo root=new NodeInfo();
+		DiagramContext context=new DiagramContext(edges,nodeMap);
+		root.setId(context.nextId());
+		root.setLabel("Enter");
+		root.setColor("#98AFC7");
+		root.setWidth(nodeWidth);
+		root.setHeight(nodeHeight);
+		root.setRoundCorner(10);
+		List<ObjectTypeNode> typeNodes=rete.getObjectTypeNodes();
+		int level=1;
+		for(ObjectTypeNode typeNode:typeNodes){
+			NodeInfo node=new NodeInfo();
+			node.setId(context.nextId());
+			node.setLabel("T");
+			node.setTitle(typeNode.getObjectTypeClass());
+			node.setColor("#97CBFF");
+			node.setLevel(level);
+			node.setWidth(nodeWidth);
+			node.setHeight(nodeHeight);
+			node.setRoundCorner(5);
+			root.addChild(node);
+			List<Line> lines=typeNode.getLines();
+			if(lines==null){
+				continue;
+			}
+			int nextLevel=level+1;
+			for(Line line:lines){
+				Edge edge=new Edge(root.getId(),node.getId());
+				edges.add(edge);
+				buildLine(line,context,node,nextLevel);
+			}
+		}
+		Box box=nodeLayout.layout(root);
+		Diagram diagram = new Diagram(edges,root);
+		if(box!=null){
+			diagram.setWidth(box.getWidth()+500);
+			diagram.setHeight(box.getHeight()+300);
+		}
+		return diagram;
+	}
+
+	private void buildLine(Line line,DiagramContext context,NodeInfo parentNode,int level){
+		Node toNode=line.getTo();
+		if(toNode==null){
+			return;
+		}
+		Map<Node,NodeInfo> nodeMap=context.getNodeMap();
+		NodeInfo newNodeInfo=null;
+		if(nodeMap.containsKey(toNode)){
+			newNodeInfo=nodeMap.get(toNode);
+			context.addEdge(new Edge(parentNode.getId(),newNodeInfo.getId()));
+			return;
+		}
+		List<Line> lines=null;
+		newNodeInfo=new NodeInfo();
+		newNodeInfo.setLevel(level);
+		newNodeInfo.setId(context.nextId());
+		newNodeInfo.setWidth(nodeWidth);
+		newNodeInfo.setHeight(nodeHeight);
+		if(toNode instanceof CriteriaNode){
+			CriteriaNode cnode=(CriteriaNode)toNode;
+			newNodeInfo.setColor("#B3D9D9");
+			newNodeInfo.setLabel("C");
+			newNodeInfo.setTitle(cnode.getCriteriaInfo());
+			newNodeInfo.setRoundCorner(nodeHeight);
+			lines=cnode.getLines();
+		}else if(toNode instanceof NamedCriteriaNode){
+			NamedCriteriaNode node=(NamedCriteriaNode)toNode;
+			newNodeInfo.setColor("#B3E9D9");
+			newNodeInfo.setLabel("C");
+			newNodeInfo.setTitle(node.getCriteriaInfo());
+			newNodeInfo.setRoundCorner(nodeHeight);
+			lines=node.getLines();
+		}else if(toNode instanceof AndNode){
+			AndNode andNode=(AndNode)toNode;
+			lines=andNode.getLines();
+			newNodeInfo.setColor("#DAB1D5");
+			newNodeInfo.setLabel("AND");
+			newNodeInfo.setRoundCorner(nodeHeight/2);
+		}else if(toNode instanceof OrNode){
+			OrNode orNode=(OrNode)toNode;
+			lines=orNode.getLines();
+			newNodeInfo.setColor("#82D900");
+			newNodeInfo.setLabel("OR");
+			newNodeInfo.setRoundCorner(nodeHeight/2);
+		}else if(toNode instanceof TerminalNode){
+			TerminalNode terminalNode=(TerminalNode)toNode;
+			newNodeInfo.setColor("orange");
+			newNodeInfo.setLabel(terminalNode.getRule().getName());
+			newNodeInfo.setTitle(terminalNode.getRule().getName());
+			newNodeInfo.setRoundCorner(0);
+		}
+		nodeMap.put(toNode, newNodeInfo);
+		parentNode.addChild(newNodeInfo);
+		context.addEdge(new Edge(parentNode.getId(),newNodeInfo.getId()));
+		if(lines==null){
+			return;
+		}
+		int nextLevel=level+1;
+		for(Line nextLine:lines){
+			buildLine(nextLine, context, newNodeInfo,nextLevel);
+		}
+	}
+	public void setKnowledgeBuilder(KnowledgeBuilder knowledgeBuilder) {
+		this.knowledgeBuilder = knowledgeBuilder;
+	}
+	
+	public void setHttpSessionKnowledgeCache(
+			HttpSessionKnowledgeCache httpSessionKnowledgeCache) {
+		this.httpSessionKnowledgeCache = httpSessionKnowledgeCache;
+	}
+
+	@Override
+	public String url() {
+		return "/retediagram";
+	}
+}

+ 110 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/diagram/ReteNodeLayout.java

@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.diagram;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Jacky.gao
+ * @since 2015129
+ */
+public class ReteNodeLayout {
+	private final int leftMargin=50;
+	private final int topMargin=50;
+	private final int nodeWidth=30;
+	private final int nodeHeight=30;
+	public Box layout(NodeInfo rootNode){
+		List<NodeInfo> children=rootNode.getChildren();
+		if(children==null){
+			return null;
+		}
+		Map<Integer,Integer> levelXPositionMap=new HashMap<Integer,Integer>();
+		Map<Integer,List<NodeInfo>> nodeLevelMap=new HashMap<Integer,List<NodeInfo>>();
+		buildNodesLevelMap(children, nodeLevelMap);
+		int maxSize = buildMaxSize(nodeLevelMap)-1;
+		int maxWidth=maxSize*nodeWidth+maxSize*leftMargin;
+		int x=maxWidth/2+leftMargin+nodeWidth;
+		rootNode.setX(x);
+		rootNode.setY(5);
+		buildChildrenNodeLocation(children,rootNode,nodeLevelMap,levelXPositionMap);
+		Box box=new Box();
+		box.setWidth(maxWidth+leftMargin*2+nodeWidth);
+		int maxHeight=nodeLevelMap.size()*nodeHeight*3+topMargin*2;
+		box.setHeight(maxHeight);
+		return box;
+	}
+	private void buildChildrenNodeLocation(List<NodeInfo> nodes,NodeInfo rootNode,Map<Integer,List<NodeInfo>> nodeLevelMap,Map<Integer,Integer> levelXPositionMap){
+		for(int i=0;i<nodes.size();i++){
+			NodeInfo node=nodes.get(i);
+			int level=node.getLevel();
+			node.setY(level*topMargin+level*nodeHeight);
+			List<NodeInfo> children=node.getChildren();
+			int xposition=0;
+			if(levelXPositionMap.containsKey(level)){
+				xposition=levelXPositionMap.get(level);
+			}
+			int rootX=rootNode.getX();
+			int levelSize=nodeLevelMap.get(level).size();
+			if(xposition==0){
+				if(levelSize>1){
+					int levelWidth=levelSize*nodeWidth+levelSize*leftMargin;
+					xposition=rootX-levelWidth/2-leftMargin;					
+				}else{
+					xposition=rootX;
+				}
+			}
+			int x=leftMargin+nodeWidth+xposition;
+			if(levelSize==1){
+				x=xposition;
+			}
+			node.setX(x);
+			levelXPositionMap.put(level, x);
+			if(children!=null){
+				buildChildrenNodeLocation(children,rootNode,nodeLevelMap,levelXPositionMap);
+			}
+		}
+	}
+	private int buildMaxSize(Map<Integer, List<NodeInfo>> nodeLevelMap) {
+		int maxSize=1;
+		for(List<NodeInfo> list:nodeLevelMap.values()){
+			if(list.size()>maxSize){
+				maxSize=list.size();
+			}
+		}
+		return maxSize;
+	}
+	private void buildNodesLevelMap(List<NodeInfo> nodes,Map<Integer,List<NodeInfo>> nodeLevelMap){
+		for(NodeInfo node:nodes){
+			int level=node.getLevel();
+			if(nodeLevelMap.containsKey(level)){
+				List<NodeInfo> levelNodes=nodeLevelMap.get(level);
+				levelNodes.add(node);
+			}else{
+				List<NodeInfo> levelNodes=new ArrayList<NodeInfo>();
+				levelNodes.add(node);
+				nodeLevelMap.put(level, levelNodes);
+			}
+			List<NodeInfo> children=node.getChildren();
+			if(children==null){
+				continue;
+			}
+			buildNodesLevelMap(children, nodeLevelMap);
+		}
+	}
+}

+ 63 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/flow/FlowDefinitionWrapper.java

@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.flow;
+
+import java.util.List;
+
+import com.bstek.urule.model.flow.FlowNode;
+import com.bstek.urule.model.flow.ProcessDefinition;
+import com.bstek.urule.model.rule.Library;
+
+/**
+ * @author Jacky.gao
+ * @since 2016727
+ */
+public class FlowDefinitionWrapper {
+
+	private String id;
+	private List<Library> libraries;
+	private List<FlowNode> nodes;
+	public FlowDefinitionWrapper(ProcessDefinition flowDefinition) {
+		this.id = flowDefinition.getId();
+		this.libraries = flowDefinition.getLibraries();
+		this.nodes = flowDefinition.getNodes();
+	}
+	
+	public List<FlowNode> getNodes() {
+		return nodes;
+	}
+
+
+	public void setNodes(List<FlowNode> nodes) {
+		this.nodes = nodes;
+	}
+
+
+	public List<Library> getLibraries() {
+		return libraries;
+	}
+	public void setLibraries(List<Library> libraries) {
+		this.libraries = libraries;
+	}
+	
+	public String getId() {
+		return id;
+	}
+	public void setId(String id) {
+		this.id = id;
+	}
+	
+}

+ 122 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/flow/RuleFlowDesignerServletHandler.java

@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.flow;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.repository.model.ResourcePackage;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.model.flow.FlowDefinition;
+import com.bstek.urule.parse.deserializer.FlowDeserializer;
+
+/**
+ * @author Jacky.gao
+ * @since 201663
+ */
+public class RuleFlowDesignerServletHandler extends RenderPageServletHandler {
+	private RepositoryService repositoryService;
+	private FlowDeserializer flowDeserializer;
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			String file=req.getParameter("file");
+			String project = buildProjectNameFromFile(file);
+			if(project!=null){
+				context.put("project", project);
+			}
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/rule-flow-designer.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+
+	public void loadFlowDefinition(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		InputStream inputStream;
+		String file=req.getParameter("file");
+		String version=req.getParameter("version");
+		file=Utils.decodeURL(file);
+		if(StringUtils.isEmpty(version)){
+			inputStream=repositoryService.readFile(file,null);
+		}else{
+			inputStream=repositoryService.readFile(file,version);
+		}
+		Element root=parseXml(inputStream);
+		FlowDefinition fd = flowDeserializer.deserialize(root);
+		inputStream.close();
+		writeObjectToJson(resp, new FlowDefinitionWrapper(fd));
+	}
+	
+	protected Element parseXml(InputStream stream){
+		SAXReader reader=new SAXReader();
+		Document document;
+		try {
+			document = reader.read(stream);
+			Element root=document.getRootElement();
+			return root;
+		} catch (DocumentException e) {
+			throw new RuleException(e);
+		}
+	}
+	
+	public void loadPackages(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String project=req.getParameter("project");
+		try{
+			List<ResourcePackage> packages=repositoryService.loadProjectResourcePackages(project);		
+			writeObjectToJson(resp, packages);
+		}catch(Exception ex){
+			throw new RuleException(ex);
+		}
+	}
+	
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+
+	public void setFlowDeserializer(FlowDeserializer flowDeserializer) {
+		this.flowDeserializer = flowDeserializer;
+	}
+	
+	@Override
+	public String url() {
+		return "/ruleflowdesigner";
+	}
+}

+ 441 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/frame/FrameServletHandler.java

@@ -0,0 +1,441 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.frame;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.EnvironmentUtils;
+import com.bstek.urule.console.User;
+import com.bstek.urule.console.repository.Repository;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.repository.model.FileType;
+import com.bstek.urule.console.repository.model.RepositoryFile;
+import com.bstek.urule.console.repository.model.Type;
+import com.bstek.urule.console.repository.model.VersionFile;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.console.servlet.RequestContext;
+
+/**
+ * @author Jacky.gao
+ * @since 201663
+ */
+public class FrameServletHandler extends RenderPageServletHandler{
+	private RepositoryService repositoryService;
+	private String welcomePage;
+	private String title;
+	private static final String CLASSIFY_COOKIE_NAME="_lib_classify";
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			context.put("welcomePage", welcomePage);
+			context.put("title", title);
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/frame.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	
+	public void fileVersions(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String path=req.getParameter("path");
+		path=Utils.decodeURL(path);
+		List<VersionFile> files=repositoryService.getVersionFiles(path);
+		writeObjectToJson(resp, files);
+	}
+	
+	public void fileSource(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String path=req.getParameter("path");
+		path=Utils.decodeURL(path);
+		InputStream inputStream=repositoryService.readFile(path,null);
+		String content=IOUtils.toString(inputStream,"utf-8");
+		Document doc=DocumentHelper.parseText(content);
+		OutputFormat format=OutputFormat.createPrettyPrint();
+		StringWriter out=new StringWriter();
+		XMLWriter writer=new XMLWriter(out, format);
+		writer.write(doc);
+		inputStream.close();
+		Map<String,Object> result=new HashMap<String,Object>();
+		result.put("content", out.toString());
+		writeObjectToJson(resp, result);
+	}
+	
+	public void importProject(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		DiskFileItemFactory factory = new DiskFileItemFactory();
+		ServletContext servletContext = req.getSession().getServletContext();
+		File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
+		factory.setRepository(repository);
+		ServletFileUpload upload = new ServletFileUpload(factory);
+		InputStream inputStream=null;
+		boolean overwriteProject=true;
+		List<FileItem> items = upload.parseRequest(req);
+		if(items.size()==0){
+			throw new ServletException("Upload file is invalid.");
+		}
+		for(FileItem item:items){
+			String name=item.getFieldName();
+			if(name.equals("overwriteProject")){
+				String overwriteProjectStr=new String(item.get());
+				overwriteProject=Boolean.valueOf(overwriteProjectStr);
+			}else if(name.equals("file")){
+				inputStream=item.getInputStream();
+			}
+		}
+		repositoryService.importXml(inputStream,overwriteProject);
+		IOUtils.closeQuietly(inputStream);
+		resp.sendRedirect(req.getContextPath()+"/urule/frame");
+	}
+	
+	public void loadFileVersions(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String file=req.getParameter("file");
+		file=Utils.decodeURL(file);
+		List<VersionFile> versions=repositoryService.getVersionFiles(file);
+		writeObjectToJson(resp, versions);
+	}
+	public void createFolder(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String fullFolderName=req.getParameter("fullFolderName");
+		fullFolderName=Utils.decodeURL(fullFolderName);
+		User user=EnvironmentUtils.getLoginUser(new RequestContext(req,resp));
+		repositoryService.createDir(fullFolderName, user);
+		loadProjects(req, resp);
+	}
+	public void copyFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String newFullPath=req.getParameter("newFullPath");
+		String oldFullPath=req.getParameter("oldFullPath");
+		newFullPath=Utils.decodeURL(newFullPath);
+		oldFullPath=Utils.decodeURL(oldFullPath);
+		InputStream inputStream=repositoryService.readFile(oldFullPath, null);
+		String content=IOUtils.toString(inputStream, "utf-8");
+		inputStream.close();
+		User user=EnvironmentUtils.getLoginUser(new RequestContext(req,resp));
+		repositoryService.createFile(newFullPath, content,user.getUsername());
+		loadProjects(req, resp);
+	}
+	
+	public void createFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String path=req.getParameter("path");
+		path=Utils.decodeURL(path);
+		String type=req.getParameter("type");
+		FileType fileType=FileType.parse(type);
+		StringBuilder content=new StringBuilder();
+		if(fileType.equals(FileType.UL)) {
+			content.append("rule \"rule01\"");
+			content.append("\n");
+			content.append("if");
+			content.append("\r\n");
+			content.append("then");
+			content.append("\r\n");
+			content.append("end");
+		}else if(fileType.equals(FileType.DecisionTable)) {
+			content.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+			content.append("<decision-table>");
+			content.append("<cell row=\"0\" col=\"2\" rowspan=\"1\"></cell>");
+			content.append("<cell row=\"0\" col=\"1\" rowspan=\"1\">");
+			content.append("<joint type=\"and\"/>");
+			content.append("</cell>");
+			content.append("<cell row=\"0\" col=\"0\" rowspan=\"1\">");
+			content.append("<joint type=\"and\"/>");
+			content.append("</cell>");
+			content.append("<cell row=\"1\" col=\"2\" rowspan=\"1\">");
+			content.append("</cell>");
+			content.append("<cell row=\"1\" col=\"1\" rowspan=\"1\">");
+			content.append("<joint type=\"and\"/>");
+			content.append("</cell>");
+			content.append("<cell row=\"1\" col=\"0\" rowspan=\"1\">");
+			content.append("<joint type=\"and\"/>");
+			content.append("</cell>");
+			content.append("<row num=\"0\" height=\"40\"/>");
+			content.append("<row num=\"1\" height=\"40\"/>");
+			content.append("<col num=\"0\" width=\"120\" type=\"Criteria\"/>");
+			content.append("<col num=\"1\" width=\"120\" type=\"Criteria\"/>");
+			content.append("<col num=\"2\" width=\"200\" type=\"Assignment\"/>");
+			content.append("</decision-table>");
+		}else if(fileType.equals(FileType.DecisionTree)){
+			content.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+			content.append("<decision-tree>");
+			content.append("<variable-tree-node></variable-tree-node>");
+			content.append("</decision-tree>");
+		}else if(fileType.equals(FileType.ScriptDecisionTable)) {
+			content.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+			content.append("<script-decision-table>");
+			content.append("<script-cell row=\"0\" col=\"2\" rowspan=\"1\"></script-cell>");
+			content.append("<script-cell row=\"0\" col=\"1\" rowspan=\"1\"></script-cell>");
+			content.append("<script-cell row=\"0\" col=\"0\" rowspan=\"1\"></script-cell>");
+			content.append("<script-cell row=\"1\" col=\"2\" rowspan=\"1\"></script-cell>");
+			content.append("<script-cell row=\"1\" col=\"1\" rowspan=\"1\"></script-cell>");
+			content.append("<script-cell row=\"1\" col=\"0\" rowspan=\"1\"></script-cell>");
+			content.append("<row num=\"0\" height=\"40\"/>");
+			content.append("<row num=\"1\" height=\"40\"/>");
+			content.append("<col num=\"0\" width=\"120\" type=\"Criteria\"/>");
+			content.append("<col num=\"1\" width=\"120\" type=\"Criteria\"/>");
+			content.append("<col num=\"2\" width=\"200\" type=\"Assignment\"/>");
+			content.append("</script-decision-table>");
+		}else if(fileType.equals(FileType.Scorecard)){
+			content.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+			content.append("<scorecard scoring-type=\"sum\" assign-target-type=\"none\">");
+			content.append("</scorecard>");
+		}else{
+			String name = getRootTagName(fileType);
+			content.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+			content.append("<" + name + ">");
+			content.append("</" + name + ">");
+		}
+		User user=EnvironmentUtils.getLoginUser(new RequestContext(req,resp));
+		repositoryService.createFile(path, content.toString(),user.getUsername());
+		RepositoryFile newFileInfo=new RepositoryFile();
+		newFileInfo.setFullPath(path);
+		if(fileType.equals(FileType.VariableLibrary)){
+			newFileInfo.setType(Type.variable);			
+		}else if(fileType.equals(FileType.ActionLibrary)){
+			newFileInfo.setType(Type.action);			
+		}else if(fileType.equals(FileType.ConstantLibrary)){
+			newFileInfo.setType(Type.constant);			
+		}else if(fileType.equals(FileType.ParameterLibrary)){
+			newFileInfo.setType(Type.parameter);			
+		}else if(fileType.equals(FileType.DecisionTable)){
+			newFileInfo.setType(Type.decisionTable);			
+		}else if(fileType.equals(FileType.ScriptDecisionTable)){
+			newFileInfo.setType(Type.scriptDecisionTable);			
+		}else if(fileType.equals(FileType.Ruleset)){
+			newFileInfo.setType(Type.rule);			
+		}else if(fileType.equals(FileType.UL)){
+			newFileInfo.setType(Type.ul);			
+		}else if(fileType.equals(FileType.DecisionTree)){
+			newFileInfo.setType(Type.decisionTree);			
+		}else if(fileType.equals(FileType.RuleFlow)){
+			newFileInfo.setType(Type.flow);			
+		}else if(fileType.equals(FileType.Scorecard)){
+			newFileInfo.setType(Type.scorecard);			
+		}
+		writeObjectToJson(resp, newFileInfo);
+	}
+	
+	private String getRootTagName(FileType type) {
+		String root = null;
+		switch(type){
+		case ActionLibrary:
+			root="action-library";
+			break;
+		case ConstantLibrary:
+			root="constant-library";
+			break;
+		case DecisionTable:
+			root="decision-table";
+			break;
+		case DecisionTree:
+			root="decision-tree";
+			break;
+		case ParameterLibrary:
+			root="parameter-library";
+			break;
+		case RuleFlow:
+			root="rule-flow";
+			break;
+		case Ruleset:
+			root="rule-set";
+			break;
+		case ScriptDecisionTable:
+			root="script-decision-table";
+			break;
+		case VariableLibrary:
+			root="variable-library";
+			break;
+		case UL:
+			root="script";
+			break;
+		case Scorecard:
+			root="scorecard";
+			break;
+		case DIR:
+			throw new IllegalArgumentException("Unsupport filetype : "+type);
+		}
+		return root;
+	}
+	
+	public void projectExistCheck(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String projectName=req.getParameter("newProjectName");
+		if(StringUtils.isEmpty(projectName)){
+			return;
+		}
+		projectName=Utils.decodeURL(projectName);
+		projectName=projectName.trim();
+		Map<String,Object> result=new HashMap<String,Object>();
+		result.put("valid", !repositoryService.fileExistCheck(projectName));
+		writeObjectToJson(resp, result);
+	}
+	public void fileExistCheck(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String fullFileName=req.getParameter("fullFileName");
+		if(StringUtils.isEmpty(fullFileName)){
+			return;
+		}
+		fullFileName=Utils.decodeURL(fullFileName);
+		fullFileName=fullFileName.trim();
+		Map<String,Object> result=new HashMap<String,Object>();
+		result.put("valid", !repositoryService.fileExistCheck(fullFileName));
+		writeObjectToJson(resp, result);
+	}
+	
+	public void deleteFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String path=req.getParameter("path");
+		path=Utils.decodeURL(path);
+		repositoryService.deleteFile(path);
+		String isFolder=req.getParameter("isFolder");
+		if(StringUtils.isNotBlank(isFolder) && isFolder.equals("true")){
+			loadProjects(req, resp);
+		}
+	}
+	
+	
+	public void exportProjectBackupFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String path=req.getParameter("path");
+		String projectPath=Utils.decodeURL(path);
+		if(StringUtils.isEmpty(projectPath)){
+			throw new RuleException("Export project not be null.");
+		}
+		SimpleDateFormat sd=new SimpleDateFormat("yyyyMMddHHmmss");
+		String projectName=projectPath.substring(1,projectPath.length());
+		String filename=projectName+"-urule-repo-"+sd.format(new Date())+".bak";
+		resp.setContentType("application/octet-stream");
+		resp.setHeader("Content-Disposition", "attachment; filename=\"" + new String(filename.getBytes("utf-8"),"iso-8859-1") + "\"");
+		resp.setHeader("content-type", "application/octet-stream");
+		OutputStream outputStream=resp.getOutputStream();
+		repositoryService.exportXml(projectPath,outputStream);
+		outputStream.flush();
+		outputStream.close();
+	}
+	
+	public void createProject(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String projectName=req.getParameter("newProjectName");
+		projectName=Utils.decodeURL(projectName);
+		boolean classify = getClassify(req,resp);
+		User user=EnvironmentUtils.getLoginUser(new RequestContext(req,resp));
+		RepositoryFile projectFileInfo=repositoryService.createProject(projectName,user,classify);
+		writeObjectToJson(resp, projectFileInfo);
+	}
+
+	
+	public void loadProjects(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		User user=EnvironmentUtils.getLoginUser(new RequestContext(req,resp));
+		boolean classify = getClassify(req,resp);
+		String projectName=req.getParameter("projectName");
+		String searchFileName=req.getParameter("searchFileName");
+		projectName=Utils.decodeURL(projectName);
+		String typesStr=req.getParameter("types");
+		FileType[] types=null;
+		if(StringUtils.isNotBlank(typesStr) && !typesStr.equals("all")){
+			if(typesStr.equals("lib")){
+				types=new FileType[]{FileType.VariableLibrary,FileType.ConstantLibrary,FileType.ParameterLibrary,FileType.ActionLibrary};
+			}else if(typesStr.equals("rule")){
+				types=new FileType[]{FileType.Ruleset,FileType.UL};
+			}else if(typesStr.equals("table")){
+				types=new FileType[]{FileType.DecisionTable,FileType.ScriptDecisionTable};
+			}else if(typesStr.equals("tree")){
+				types=new FileType[]{FileType.DecisionTree};
+			}else if(typesStr.equals("flow")){
+				types=new FileType[]{FileType.RuleFlow};
+			}
+		}
+		Repository repo=repositoryService.loadRepository(projectName, user.getCompanyId(),classify,types,searchFileName);
+		Map<String,Object> map=new HashMap<String,Object>();
+		map.put("repo", repo);
+		map.put("classify", classify);
+		writeObjectToJson(resp, map);
+	}
+
+	private boolean getClassify(HttpServletRequest req,HttpServletResponse resp) {
+		String classifyValue=req.getParameter("classify");
+		if(StringUtils.isBlank(classifyValue)){
+			Cookie[] cookies=req.getCookies();
+			if(cookies!=null){				
+				for(Cookie cookie:cookies){
+					if(CLASSIFY_COOKIE_NAME.equals(cookie.getName())){
+						classifyValue=cookie.getValue();
+						break;
+					}
+				}
+			}
+		}else{
+			Cookie classifyCookie=new Cookie(CLASSIFY_COOKIE_NAME,classifyValue);
+			classifyCookie.setMaxAge(2100000000);
+			resp.addCookie(classifyCookie);
+		}
+		boolean classify=true;
+		if(StringUtils.isNotBlank(classifyValue)){
+			classify=Boolean.valueOf(classifyValue);
+		}
+		return classify;
+	}
+	
+	public void fileRename(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String path=req.getParameter("path");
+		path=Utils.decodeURL(path);
+		String newPath=req.getParameter("newPath");
+		newPath=Utils.decodeURL(newPath);
+		repositoryService.fileRename(path, newPath);
+		loadProjects(req, resp);
+	}
+	
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+	public void setWelcomePage(String welcomePage) {
+		this.welcomePage = welcomePage;
+	}
+	public void setTitle(String title) {
+		this.title = title;
+	}
+	
+	@Override
+	public String url() {
+		return "/frame";
+	}
+}

+ 81 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/knowledge/LoadKnowledgeServletHandler.java

@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.knowledge;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.runtime.KnowledgePackage;
+import com.bstek.urule.runtime.KnowledgePackageWrapper;
+import com.bstek.urule.runtime.cache.CacheUtils;
+import com.bstek.urule.runtime.service.KnowledgePackageService;
+
+/**
+ * @author Jacky.gao
+ * @since 2016817
+ */
+public class LoadKnowledgeServletHandler  extends RenderPageServletHandler{
+	private KnowledgePackageService knowledgePackageService;
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String packageId=req.getParameter("packageId");
+		if(StringUtils.isEmpty(packageId)){
+			resp.setContentType("text/html");
+			PrintWriter pw=resp.getWriter();
+			pw.write("<html>");
+			pw.write("<header>");
+			pw.write("</header>");
+			pw.write("<body>");
+			pw.write("<h1>packageId can not be null<h1>");
+			pw.write("</body>");
+			pw.write("</html>");
+			pw.flush();
+			pw.close();
+			return;
+		}
+		packageId=Utils.decodeURL(packageId);
+		String timestamp=req.getParameter("timestamp");
+		KnowledgePackage knowledgePackage=CacheUtils.getKnowledgeCache().getKnowledge(packageId);
+		if(knowledgePackage==null){
+			knowledgePackage=knowledgePackageService.buildKnowledgePackage(packageId);
+			CacheUtils.getKnowledgeCache().putKnowledge(packageId, knowledgePackage);
+		}
+		if(StringUtils.isNotEmpty(timestamp)){
+			long remoteTimestamp=Long.valueOf(timestamp);
+			long localTimestamp=knowledgePackage.getTimestamp();
+			if(localTimestamp>remoteTimestamp){
+				writeObjectToJson(resp, new KnowledgePackageWrapper(knowledgePackage));
+			}
+		}else{
+			writeObjectToJson(resp, new KnowledgePackageWrapper(knowledgePackage));
+		}
+	}
+	@Override
+	public String url() {
+		return "/loadknowledge";
+	}
+	public void setKnowledgePackageService(KnowledgePackageService knowledgePackageService) {
+		this.knowledgePackageService = knowledgePackageService;
+	}
+}

+ 56 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/parameter/ParameterServletHandler.java

@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.parameter;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+
+/**
+ * @author Jacky.gao
+ * @since 201681
+ */
+public class ParameterServletHandler extends RenderPageServletHandler{
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/parameter-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	@Override
+	public String url() {
+		return "/parametereditor";
+	}
+	
+}

+ 152 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/permission/PermissionConfigServletHandler.java

@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.permission;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.console.EnvironmentUtils;
+import com.bstek.urule.console.User;
+import com.bstek.urule.console.exception.NoPermissionException;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.repository.RepositoryServiceImpl;
+import com.bstek.urule.console.repository.model.RepositoryFile;
+import com.bstek.urule.console.repository.permission.PermissionService;
+import com.bstek.urule.console.repository.permission.PermissionStore;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.console.servlet.RequestContext;
+
+/**
+ * @author Jacky.gao
+ * @since 2016830
+ */
+public class PermissionConfigServletHandler extends RenderPageServletHandler{
+	private RepositoryService repositoryService;
+	private PermissionStore permissionStore;
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		if(!((PermissionService)permissionStore).isAdmin()){
+			throw new NoPermissionException();
+		}
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/permission-config-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	public void loadResourceSecurityConfigs(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String companyId=EnvironmentUtils.getLoginUser(new RequestContext(req, resp)).getCompanyId();
+		List<UserPermission> permissions=repositoryService.loadResourceSecurityConfigs(companyId);
+		List<User> users=EnvironmentUtils.getEnvironmentProvider().getUsers();
+		if(users==null)users=new ArrayList<User>();
+		List<UserPermission> result=new ArrayList<UserPermission>();
+		for(User user:users){
+			if(user.isAdmin()){
+				continue;
+			}
+			if(companyId!=null){
+				if(user.getCompanyId()==null){
+					continue;
+				}
+				if(!user.getCompanyId().equals(companyId)){
+					continue;
+				}
+			}
+			boolean exist=false;
+			for(UserPermission p:permissions){
+				if(p.getUsername().equals(user.getUsername())){
+					exist=true;
+					break;
+				}
+			}
+			if(exist){
+				continue;
+			}
+			UserPermission up=new UserPermission();
+			up.setProjectConfigs(new ArrayList<ProjectConfig>());
+			up.setUsername(user.getUsername());
+			result.add(up);
+		}
+		result.addAll(permissions);
+		List<RepositoryFile> projects=repositoryService.loadProject(companyId);
+		for(UserPermission p:result){
+			buildProjectConfigs(projects, p);
+		}
+		writeObjectToJson(resp, result);
+	}
+	
+	private void buildProjectConfigs(List<RepositoryFile> projects,UserPermission p){
+		List<ProjectConfig> configs=p.getProjectConfigs();
+		if(configs==null){
+			configs=new ArrayList<ProjectConfig>();
+			p.setProjectConfigs(configs);
+		}
+		for(RepositoryFile project:projects){
+			boolean exist=false;
+			for(ProjectConfig c:p.getProjectConfigs()){
+				if(project.getName().equals(c.getProject())){
+					exist=true;
+					break;
+				}
+			}
+			if(exist){
+				continue;
+			}
+			ProjectConfig config=new ProjectConfig();
+			config.setProject(project.getName());
+			configs.add(config);
+		}
+	}
+	
+	public void saveResourceSecurityConfigs(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		User user=EnvironmentUtils.getLoginUser(new RequestContext(req, resp));
+		String companyId=user.getCompanyId();
+		String content=req.getParameter("content");
+		String path=RepositoryServiceImpl.RESOURCE_SECURITY_CONFIG_FILE+(companyId==null ? "" : companyId);
+		repositoryService.saveFile(path, content, user.getUsername(), false,null);
+		permissionStore.refreshPermissionStore();
+	}
+	
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+	
+	public void setPermissionStore(PermissionStore permissionStore) {
+		this.permissionStore = permissionStore;
+	}
+	
+	@Override
+	public String url() {
+		return "/permission";
+	}
+}

+ 188 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/permission/ProjectConfig.java

@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.permission;
+/**
+ * @author Jacky.gao
+ * @since 2016830
+ */
+public class ProjectConfig {
+	private String project;
+	private boolean readProject;
+	
+	private boolean readPackage;
+	private boolean writePackage;
+	
+	private boolean readVariableFile;
+	private boolean writeVariableFile;
+	
+	private boolean readParameterFile;
+	private boolean writeParameterFile;
+	
+	private boolean readConstantFile;
+	private boolean writeConstantFile;
+	
+	private boolean readActionFile;
+	private boolean writeActionFile;
+		
+	private boolean readRuleFile;
+	private boolean writeRuleFile;
+	
+	private boolean readScorecardFile;
+	private boolean writeScorecardFile;
+	
+	private boolean readDecisionTableFile;
+	private boolean writeDecisionTableFile;
+		
+	private boolean readDecisionTreeFile;
+	private boolean writeDecisionTreeFile;
+	
+	private boolean readFlowFile;
+	private boolean writeFlowFile;
+	
+	public String getProject() {
+		return project;
+	}
+	public void setProject(String project) {
+		this.project = project;
+	}
+	
+	public boolean isReadProject() {
+		return readProject;
+	}
+	public void setReadProject(boolean readProject) {
+		this.readProject = readProject;
+	}
+	public boolean isReadPackage() {
+		return readPackage;
+	}
+	public void setReadPackage(boolean readPackage) {
+		this.readPackage = readPackage;
+	}
+	public boolean isWritePackage() {
+		return writePackage;
+	}
+	public void setWritePackage(boolean writePackage) {
+		this.writePackage = writePackage;
+	}
+	public boolean isReadVariableFile() {
+		return readVariableFile;
+	}
+	public void setReadVariableFile(boolean readVariableFile) {
+		this.readVariableFile = readVariableFile;
+	}
+	public boolean isWriteVariableFile() {
+		return writeVariableFile;
+	}
+	public void setWriteVariableFile(boolean writeVariableFile) {
+		this.writeVariableFile = writeVariableFile;
+	}
+	public boolean isReadParameterFile() {
+		return readParameterFile;
+	}
+	public void setReadParameterFile(boolean readParameterFile) {
+		this.readParameterFile = readParameterFile;
+	}
+	public boolean isWriteParameterFile() {
+		return writeParameterFile;
+	}
+	public void setWriteParameterFile(boolean writeParameterFile) {
+		this.writeParameterFile = writeParameterFile;
+	}
+	public boolean isReadConstantFile() {
+		return readConstantFile;
+	}
+	public void setReadConstantFile(boolean readConstantFile) {
+		this.readConstantFile = readConstantFile;
+	}
+	public boolean isWriteConstantFile() {
+		return writeConstantFile;
+	}
+	public void setWriteConstantFile(boolean writeConstantFile) {
+		this.writeConstantFile = writeConstantFile;
+	}
+	public boolean isReadActionFile() {
+		return readActionFile;
+	}
+	public void setReadActionFile(boolean readActionFile) {
+		this.readActionFile = readActionFile;
+	}
+	public boolean isWriteActionFile() {
+		return writeActionFile;
+	}
+	public void setWriteActionFile(boolean writeActionFile) {
+		this.writeActionFile = writeActionFile;
+	}
+	public boolean isReadRuleFile() {
+		return readRuleFile;
+	}
+	public void setReadRuleFile(boolean readRuleFile) {
+		this.readRuleFile = readRuleFile;
+	}
+	public boolean isWriteRuleFile() {
+		return writeRuleFile;
+	}
+	public void setWriteRuleFile(boolean writeRuleFile) {
+		this.writeRuleFile = writeRuleFile;
+	}
+	public boolean isReadDecisionTableFile() {
+		return readDecisionTableFile;
+	}
+	public void setReadDecisionTableFile(boolean readDecisionTableFile) {
+		this.readDecisionTableFile = readDecisionTableFile;
+	}
+	public boolean isWriteDecisionTableFile() {
+		return writeDecisionTableFile;
+	}
+	public void setWriteDecisionTableFile(boolean writeDecisionTableFile) {
+		this.writeDecisionTableFile = writeDecisionTableFile;
+	}
+	public boolean isReadDecisionTreeFile() {
+		return readDecisionTreeFile;
+	}
+	public void setReadDecisionTreeFile(boolean readDecisionTreeFile) {
+		this.readDecisionTreeFile = readDecisionTreeFile;
+	}
+	public boolean isWriteDecisionTreeFile() {
+		return writeDecisionTreeFile;
+	}
+	public void setWriteDecisionTreeFile(boolean writeDecisionTreeFile) {
+		this.writeDecisionTreeFile = writeDecisionTreeFile;
+	}
+	public boolean isReadFlowFile() {
+		return readFlowFile;
+	}
+	public void setReadFlowFile(boolean readFlowFile) {
+		this.readFlowFile = readFlowFile;
+	}
+	public boolean isWriteFlowFile() {
+		return writeFlowFile;
+	}
+	public void setWriteFlowFile(boolean writeFlowFile) {
+		this.writeFlowFile = writeFlowFile;
+	}
+	public boolean isReadScorecardFile() {
+		return readScorecardFile;
+	}
+	public void setReadScorecardFile(boolean readScorecardFile) {
+		this.readScorecardFile = readScorecardFile;
+	}
+	public boolean isWriteScorecardFile() {
+		return writeScorecardFile;
+	}
+	public void setWriteScorecardFile(boolean writeScorecardFile) {
+		this.writeScorecardFile = writeScorecardFile;
+	}
+}

+ 39 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/permission/UserPermission.java

@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.permission;
+
+import java.util.List;
+
+/**
+ * @author Jacky.gao
+ * @since 2016830
+ */
+public class UserPermission {
+	private String username;
+	private List<ProjectConfig> projectConfigs;
+	public String getUsername() {
+		return username;
+	}
+	public void setUsername(String username) {
+		this.username = username;
+	}
+	public List<ProjectConfig> getProjectConfigs() {
+		return projectConfigs;
+	}
+	public void setProjectConfigs(List<ProjectConfig> projectConfigs) {
+		this.projectConfigs = projectConfigs;
+	}
+}

+ 69 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/respackage/HttpSessionKnowledgeCache.java

@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.respackage;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * @author Jacky.gao
+ * @since 2017820
+ */
+public class HttpSessionKnowledgeCache {
+	private Map<String,SessionObject> sessionMap=new HashMap<String,SessionObject>();
+	public Object get(HttpServletRequest req,String key){
+		SessionObject sessionObject = getSessionObject(req);
+		return sessionObject.get(key);
+	}
+	public void put(HttpServletRequest req,String key,Object obj){
+		SessionObject sessionObject = getSessionObject(req);
+		sessionObject.put(key, obj);
+	}
+	public void remove(HttpServletRequest req,String key){
+		SessionObject sessionObject = getSessionObject(req);
+		sessionObject.remove(key);
+	}
+	private SessionObject getSessionObject(HttpServletRequest req) {
+		clean();
+		String sessionId=req.getSession().getId();
+		SessionObject sessionObject=null;
+		if(sessionMap.containsKey(sessionId)){
+			sessionObject=sessionMap.get(sessionId);
+		}else{
+			sessionObject=new SessionObject();
+			sessionMap.put(sessionId, sessionObject);
+		}
+		return sessionObject;
+	}
+	
+	private void clean(){
+		List<String> list=new ArrayList<String>();
+		for(String key:sessionMap.keySet()){
+			SessionObject obj=sessionMap.get(key);
+			if(obj.isExpired()){
+				list.add(key);
+			}
+		}
+		for(String key:list){
+			sessionMap.remove(key);
+		}
+	}
+}

+ 856 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/respackage/PackageServletHandler.java

@@ -0,0 +1,856 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.respackage;
+
+import java.awt.Color;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFColor;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+import com.bstek.urule.Configure;
+import com.bstek.urule.KnowledgePackageReceiverServlet;
+import com.bstek.urule.RuleException;
+import com.bstek.urule.Utils;
+import com.bstek.urule.builder.KnowledgeBase;
+import com.bstek.urule.builder.KnowledgeBuilder;
+import com.bstek.urule.builder.ResourceBase;
+import com.bstek.urule.console.EnvironmentUtils;
+import com.bstek.urule.console.User;
+import com.bstek.urule.console.repository.ClientConfig;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.repository.RepositoryServiceImpl;
+import com.bstek.urule.console.repository.model.ResourcePackage;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.console.servlet.RequestContext;
+import com.bstek.urule.model.GeneralEntity;
+import com.bstek.urule.model.flow.FlowDefinition;
+import com.bstek.urule.model.library.Datatype;
+import com.bstek.urule.model.library.variable.Variable;
+import com.bstek.urule.model.library.variable.VariableCategory;
+import com.bstek.urule.model.rule.RuleInfo;
+import com.bstek.urule.runtime.KnowledgePackage;
+import com.bstek.urule.runtime.KnowledgePackageWrapper;
+import com.bstek.urule.runtime.KnowledgeSession;
+import com.bstek.urule.runtime.KnowledgeSessionFactory;
+import com.bstek.urule.runtime.cache.CacheUtils;
+import com.bstek.urule.runtime.response.ExecutionResponse;
+import com.bstek.urule.runtime.response.ExecutionResponseImpl;
+
+/**
+ * @author Jacky.gao
+ * @since 201663
+ */
+public class PackageServletHandler extends RenderPageServletHandler {
+	public static final String KB_KEY="_kb";
+	public static final String VCS_KEY="_vcs";
+	public static final String IMPORT_EXCEL_DATA="_import_excel_data";
+	private RepositoryService repositoryService;
+	private KnowledgeBuilder knowledgeBuilder;
+	private HttpSessionKnowledgeCache httpSessionKnowledgeCache;
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/package-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	public void loadPackages(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String project=req.getParameter("project");
+		project=Utils.decodeURL(project);
+		List<ResourcePackage> packages=repositoryService.loadProjectResourcePackages(project);
+		writeObjectToJson(resp, packages);
+	}
+	
+	@SuppressWarnings("unchecked")
+	public void exportExcelTemplate(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		List<VariableCategory> variableCategories=(List<VariableCategory>)httpSessionKnowledgeCache.get(req, VCS_KEY);
+		if(variableCategories==null){
+			KnowledgeBase knowledgeBase=buildKnowledgeBase(req);
+			variableCategories=knowledgeBase.getResourceLibrary().getVariableCategories();
+		}
+		SXSSFWorkbook wb = new SXSSFWorkbook();
+		XSSFCellStyle style=(XSSFCellStyle)wb.createCellStyle();
+		Color c=new Color(147,208,15);
+		XSSFColor xssfColor=new XSSFColor(c);
+		style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+		style.setFillForegroundColor(xssfColor);
+		for(VariableCategory vc:variableCategories){
+			buildSheet(wb, vc,style);
+		}
+		resp.setContentType("application/x-xls");
+		resp.setHeader("Content-Disposition","attachment; filename=urule-batch-test-template.xlsx");
+		OutputStream outputStream=resp.getOutputStream();
+		wb.write(outputStream);;
+		outputStream.flush();
+		outputStream.close();
+	}
+	
+	private void buildSheet(SXSSFWorkbook wb,VariableCategory vc,XSSFCellStyle style){
+		String name=vc.getName();
+		Sheet sheet=wb.createSheet(name);
+		Row row=sheet.createRow(0);
+		List<Variable> variables=vc.getVariables();
+		for(int i=0;i<variables.size();i++){
+			sheet.setColumnWidth(i,4000);
+			Cell cell=row.createCell(i);
+			Variable var=variables.get(i);
+			cell.setCellValue(var.getLabel());
+			cell.setCellStyle(style);
+		}
+	}
+	
+	public void importExcelTemplate(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		DiskFileItemFactory factory=new DiskFileItemFactory();
+		ServletFileUpload upload = new ServletFileUpload(factory);
+		List<FileItem> items = upload.parseRequest(req);
+		Iterator<FileItem> itr = items.iterator();
+		List<Map<String,Object>> mapData=null;
+		while (itr.hasNext()) {
+			FileItem item = (FileItem) itr.next();
+			String name=item.getFieldName();
+			if(!name.equals("file")){
+				continue;
+			}
+			InputStream stream=item.getInputStream();
+			mapData=parseExcel(stream);
+			httpSessionKnowledgeCache.put(req, IMPORT_EXCEL_DATA, mapData);
+			stream.close();
+			break;
+		}
+		httpSessionKnowledgeCache.put(req, IMPORT_EXCEL_DATA, mapData);
+		writeObjectToJson(resp, mapData);
+	}
+
+	@SuppressWarnings("resource")
+	private List<Map<String,Object>> parseExcel(InputStream stream) throws Exception {
+		List<Map<String,Object>> mapList=new ArrayList<Map<String,Object>>();
+		XSSFWorkbook wb = new XSSFWorkbook(stream);
+		for (int i = 0; i < wb.getNumberOfSheets(); i++) {
+			XSSFSheet sheet = wb.getSheetAt(i);
+			if (sheet == null) {
+				continue;
+			}
+			String name = sheet.getSheetName();
+			Map<String,Object> map=new HashMap<String,Object>();
+			map.put("name",name);
+			map.put("data", buildVariables(sheet));
+			mapList.add(map);
+		}
+		return mapList;
+	}
+	
+	private List<Map<String,String>> buildVariables(XSSFSheet sheet){
+		Map<Integer,String> headerMap=new HashMap<Integer,String>();
+		List<Map<String,String>> mapList=new ArrayList<Map<String,String>>();
+		int totalRow=sheet.getLastRowNum();
+		XSSFRow headerRow=sheet.getRow(0);
+		int totalColumn=headerRow.getLastCellNum();
+		Map<String,String> noDataRowMap=new HashMap<String,String>();
+		for(int i=0;i<totalColumn;i++){
+			XSSFCell cell=headerRow.getCell(i);
+			String value=cell.getStringCellValue();
+			headerMap.put(i, value);
+			String headerName=value.replaceAll("\\.", "-");
+			noDataRowMap.put(headerName, null);
+		}
+		for(int i=1;i<=totalRow;i++){
+			XSSFRow row=sheet.getRow(i);
+			if(row==null){
+				continue;
+			}
+			Map<String,String> map=new HashMap<String,String>(); 
+			mapList.add(map);
+			for(int j=0;j<totalColumn;j++){
+				XSSFCell cell=row.getCell(j);
+				String headerName=headerMap.get(j);
+				if(headerName==null){
+					continue;
+				}
+				if(cell==null){
+					headerName=headerName.replaceAll("\\.", "-");
+					map.put(headerName, "");
+				}else{
+					String value="";
+					int cellType=cell.getCellType();
+					switch(cellType){
+					case Cell.CELL_TYPE_STRING:
+						value=cell.getStringCellValue();
+						break;
+					case Cell.CELL_TYPE_BLANK:
+						value="";
+						break;
+					case Cell.CELL_TYPE_BOOLEAN:
+						value=String.valueOf(cell.getBooleanCellValue());
+						break;
+					case Cell.CELL_TYPE_NUMERIC:
+						value=String.valueOf(cell.getNumericCellValue());
+						break;
+					case Cell.CELL_TYPE_ERROR:
+						value="";
+						break;
+					case Cell.CELL_TYPE_FORMULA:
+						value=cell.getCellFormula();
+						break;
+					}
+					if(value==null){
+						value="";
+					}
+					headerName=headerName.replaceAll("\\.", "-");
+					map.put(headerName, value);
+				}
+			}
+		}
+		if(mapList.size()==0){
+			mapList.add(noDataRowMap);
+		}
+		return mapList;
+	}
+
+	
+	public void loadFlows(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		KnowledgeBase knowledgeBase=(KnowledgeBase)httpSessionKnowledgeCache.get(req, KB_KEY);
+		Collection<FlowDefinition> col=knowledgeBase.getFlowMap().values();
+		writeObjectToJson(resp, col);
+	}
+	
+	public void pushKnowledgePackageToClients(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String project=req.getParameter("project");
+		project=Utils.decodeURL(project);
+		String packageId=project+"/"+Utils.decodeURL(req.getParameter("packageId"));
+		if(packageId.startsWith("/")){
+			packageId=packageId.substring(1,packageId.length());
+		}
+		KnowledgePackage knowledgePackage=CacheUtils.getKnowledgeCache().getKnowledge(packageId);
+		
+		ObjectMapper mapper=new ObjectMapper();
+		mapper.setSerializationInclusion(Inclusion.NON_NULL);
+		mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,false);
+		mapper.setDateFormat(new SimpleDateFormat(Configure.getDateFormat()));
+		StringWriter writer=new StringWriter();
+		mapper.writeValue(writer, new KnowledgePackageWrapper(knowledgePackage));
+		String content=writer.getBuffer().toString();
+		writer.close();
+		StringBuffer sb=new StringBuffer();
+		List<ClientConfig> clients=repositoryService.loadClientConfigs(project);
+		int i=0;
+		for(ClientConfig config:clients){
+			if(i>0){
+				sb.append("<br>");
+			}
+			boolean result=pushKnowledgePackage(packageId,content,config.getClient());
+			if(result){
+				sb.append("<span class=\"text-info\" style='line-height:30px'>推送到客户端:"+config.getName()+":"+config.getClient()+" 成功</span>");
+			}else{
+				sb.append("<span class=\"text-danger\" style='line-height:30px'>推送到客户端:"+config.getName()+":"+config.getClient()+" 失败</span>");
+			}
+			i++;
+		}
+		Map<String,Object> map=new HashMap<String,Object>();
+		map.put("info", sb.toString());
+		writeObjectToJson(resp, map);
+	}
+	
+	private boolean pushKnowledgePackage(String packageId,String content,String client){
+		HttpURLConnection connection=null;
+		try{
+			if(client.endsWith("/")){
+				client=client.substring(0,client.length()-1);
+			}
+			String clientUrl=client+KnowledgePackageReceiverServlet.URL;
+			content="packageId="+URLEncoder.encode(packageId, "utf-8")+"&content="+URLEncoder.encode(content, "utf-8");
+			URL url=new URL(clientUrl);
+			connection=(HttpURLConnection)url.openConnection();
+			connection.setRequestMethod("POST");
+			connection.setRequestProperty("Charset", "UTF-8");
+			connection.setRequestProperty("Accept-Charset", "utf-8");
+			connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+			connection.setUseCaches(false);
+			connection.setDoOutput(true);
+			connection.setDoInput(true);
+			connection.connect();
+			OutputStream outputStream=connection.getOutputStream();
+			DataOutputStream wr = new DataOutputStream (connection.getOutputStream());
+			wr.writeBytes(content);
+			wr.flush();
+			wr.close();
+			if (connection.getResponseCode() >= 300) {
+                return false;
+            }
+			InputStream inputStream=connection.getInputStream();
+			String result=IOUtils.toString(inputStream);
+			outputStream.close();
+			inputStream.close();
+			if(!result.equals("ok")){
+				return false;
+			}
+			return true;
+		}catch(Exception ex){
+			ex.printStackTrace();
+			return false;
+		}finally {
+			if(connection!=null){
+				connection.disconnect();
+			}
+		}
+	}
+	
+	
+	public void refreshKnowledgeCache(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String project=req.getParameter("project");
+		project=Utils.decodeURL(project);
+		String packageId=project+"/"+Utils.decodeURL(req.getParameter("packageId"));
+		if(packageId.startsWith("/")){
+			packageId=packageId.substring(1,packageId.length());
+		}
+		KnowledgeBase knowledgeBase= buildKnowledgeBase(req);
+		KnowledgePackage knowledgePackage=knowledgeBase.getKnowledgePackage();
+		CacheUtils.getKnowledgeCache().putKnowledge(packageId, knowledgePackage);
+		Map<String,Object> map=new HashMap<String,Object>();
+		List<ClientConfig> clients=repositoryService.loadClientConfigs(project);
+		if(clients.size()>0){
+			StringBuffer sb=new StringBuffer();
+			int i=1;
+			for(ClientConfig config:clients){
+				if(i>1){
+					sb.append("<br>");
+				}
+				sb.append(config.getName()+":"+config.getClient());
+				i++;
+			}
+			map.put("clientInfo", sb.toString());
+		}
+		writeObjectToJson(resp, map);
+	}
+	
+	public void loadForTestVariableCategories(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		KnowledgeBase knowledgeBase = buildKnowledgeBase(req);
+		List<VariableCategory> vcs=knowledgeBase.getResourceLibrary().getVariableCategories();
+		httpSessionKnowledgeCache.put(req, VCS_KEY, vcs);
+		writeObjectToJson(resp, vcs);
+	}
+	
+	private KnowledgeBase buildKnowledgeBase(HttpServletRequest req) throws IOException{
+		String files=req.getParameter("files");
+		files=Utils.decodeURL(files);
+		ResourceBase resourceBase=knowledgeBuilder.newResourceBase();
+		String[] paths=files.split(";");
+		for(String path:paths){
+			String[] subpaths=path.split(",");
+			path=subpaths[0];
+			String version=null;
+			if(subpaths.length>1){
+				version=subpaths[1];
+			}
+			resourceBase.addResource(path,version);
+		}
+		KnowledgeBase knowledgeBase=knowledgeBuilder.buildKnowledgeBase(resourceBase);
+		httpSessionKnowledgeCache.remove(req, KB_KEY);
+		httpSessionKnowledgeCache.put(req, KB_KEY, knowledgeBase);
+		return knowledgeBase;
+	}
+	
+	
+	public void saveResourcePackages(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String project=req.getParameter("project");
+		project=Utils.decodeURL(project);
+		String path=project+"/"+RepositoryServiceImpl.RES_PACKGE_FILE;
+		String xml=req.getParameter("xml");
+		User user=EnvironmentUtils.getLoginUser(new RequestContext(req,resp));
+		repositoryService.saveFile(path, xml, user.getUsername(), false,null);
+	}
+	
+	@SuppressWarnings("unchecked")
+	private List<VariableCategory> mapToVariableCategories(List<Map<String,Object>> mapList){
+		List<VariableCategory> list=new ArrayList<VariableCategory>();
+		for(Map<String,Object> map:mapList){
+			VariableCategory category=new VariableCategory();
+			list.add(category);
+			for(String key:map.keySet()){
+				if(key.equals("name")){
+					category.setName((String)map.get(key));
+				}else if(key.equals("clazz")){
+					category.setClazz((String)map.get(key));
+				}else if(key.equals("variables")){
+					List<Map<String,Object>> variables=(List<Map<String,Object>>)map.get(key);
+					if(variables!=null){
+						for(Map<String,Object> m:variables){
+							Variable var=new Variable();
+							category.addVariable(var);
+							for(String varName:m.keySet()){
+								if(varName.equals("name")){
+									var.setName((String)m.get(varName));
+								}else if(varName.equals("label")){
+									var.setLabel((String)m.get(varName));
+								}else if(varName.equals("type")){
+									var.setType(Datatype.valueOf((String)m.get(varName)));
+								}else if(varName.equals("defaultValue")){
+									var.setDefaultValue((String)m.get(varName));
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		return list;
+	}
+	
+	
+	@SuppressWarnings("unchecked")
+	public void doBatchTest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String flowId=req.getParameter("flowId");
+		List<VariableCategory> vcs=(List<VariableCategory>)httpSessionKnowledgeCache.get(req, VCS_KEY);
+		if(vcs==null){
+			vcs=buildKnowledgeBase(req).getResourceLibrary().getVariableCategories();
+		}
+		Map<String,VariableCategory> vcmap=new HashMap<String,VariableCategory>();
+		for(VariableCategory vc:vcs){
+			vcmap.put(vc.getName(), vc);
+		}
+		List<Map<String,Object>> data=(List<Map<String,Object>>)httpSessionKnowledgeCache.get(req, IMPORT_EXCEL_DATA);
+		if(data==null){
+			throw new RuleException("Import excel data for test has expired,please import the excel and try again.");
+		}
+		Map<String,List<Object>> factMap=new HashMap<String,List<Object>>();
+		for(Map<String,Object> map:data){
+			String name=(String)map.get("name");
+			VariableCategory vc=vcmap.get(name);
+			if(vc==null){
+				continue;
+			}
+			String clazz=vc.getClazz();
+			List<Map<String,Object>> rowList=(List<Map<String,Object>>)map.get("data");
+			List<Variable> variables=vc.getVariables();
+			List<Object> factList=new ArrayList<Object>();
+			for(Map<String,Object> rowMap:rowList){
+				Object entity=null;
+				if(vc.getName().equals(VariableCategory.PARAM_CATEGORY)){
+					entity=new HashMap<String,Object>();
+				}else{
+					entity=new GeneralEntity(clazz);
+				}
+				buildObject(entity, rowMap,variables);
+				factList.add(entity);
+			}
+			factMap.put(name, factList);
+		}
+		if(factMap.size()==0){
+			throw new RuleException("Import data cannot match current knowledge package.");
+		}
+		int rowSize=0;
+		List<String> keyList=new ArrayList<String>();
+		for(String key:factMap.keySet()){
+			keyList.add(key);
+			List<Object> facts=factMap.get(key);
+			if(facts.size()>rowSize){
+				rowSize=facts.size();
+			}
+		}
+		List<Map<String,Object>> resultList=new ArrayList<Map<String,Object>>();
+		int mapSize=factMap.size();
+		KnowledgeBase knowledgeBase=(KnowledgeBase)httpSessionKnowledgeCache.get(req, KB_KEY);
+		KnowledgePackage knowledgePackage=knowledgeBase.getKnowledgePackage();
+		KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
+		long start=System.currentTimeMillis();
+		for(int i=0;i<rowSize;i++){
+			Map<String,Object> parameterMap=null;
+			for(int j=0;j<mapSize;j++){
+				String categoryName=keyList.get(j);
+				Object fact=fetchFact(factMap,keyList,j,i);
+				if(fact==null){
+					continue;
+				}
+				if((fact instanceof Map) && !(fact instanceof GeneralEntity)){
+					parameterMap=(Map<String,Object>)fact;
+				}else{
+					session.insert(fact);
+					buildResult(resultList,categoryName,fact);
+				}
+			}
+			if(StringUtils.isNotEmpty(flowId)){
+				if(parameterMap!=null){
+					session.startProcess(flowId,parameterMap);
+				}else{
+					session.startProcess(flowId);
+				}
+			}else{
+				if(parameterMap==null){
+					session.fireRules();			
+				}else{
+					session.fireRules(parameterMap);
+					Map<String,Object> p=new HashMap<String,Object>();
+					p.putAll(session.getParameters());
+					p.remove("return_to_");
+					buildResult(resultList,VariableCategory.PARAM_CATEGORY,p);
+				}
+			}
+		}
+		long end=System.currentTimeMillis();
+		long elapse=end-start;
+		StringBuffer sb=new StringBuffer();
+		if(StringUtils.isNotEmpty(flowId)){
+			sb.append("共执行规则流");
+			sb.append("["+flowId+"]");
+			sb.append(rowSize);
+			sb.append("次,");
+		}else{
+			sb.append("共测试规则");
+			sb.append(rowSize);
+			sb.append("次,");
+		}
+		sb.append(""+"耗时:"+elapse+"ms");
+		Map<String,Object> result=new HashMap<String,Object>();
+		result.put("info", sb.toString());
+		result.put("data", resultList);
+		writeObjectToJson(resp, result);
+	}
+	
+	
+	@SuppressWarnings("unchecked")
+	private void buildResult(List<Map<String,Object>> list,String categoryName,Object fact){
+		List<Object> rowList=null;
+		for(Map<String,Object> map:list){
+			if(map.get("name").equals(categoryName)){
+				rowList=(List<Object>)map.get("data");
+				break;
+			}
+		}
+		if(rowList==null){
+			rowList=new ArrayList<Object>();
+			Map<String,Object> dataMap=new HashMap<String,Object>();
+			dataMap.put("name", categoryName);
+			dataMap.put("data", rowList);
+			dataMap.put("id", UUID.randomUUID().toString());
+			list.add(dataMap);
+		}
+		rowList.add(fact);
+	}
+
+	private Object fetchFact(Map<String,List<Object>> factMap,List<String> keyList,int i,int objectIndex){
+		if(i>keyList.size()){
+			return null;
+		}
+		String name=keyList.get(i);
+		List<Object> factList = factMap.get(name);
+		if(factList==null){
+			return null;
+		}
+		if(objectIndex>=factList.size()){
+			return null;
+		}
+		return factList.get(objectIndex);
+	}
+	
+
+	private void buildObject(Object obj,Map<String,Object> map,List<Variable> variables){
+		for(String name:map.keySet()){
+			name=name.replaceAll("-", "\\.");
+			if(name.indexOf(".")!=-1){
+				instanceChildObject(obj,name);
+			}
+			Object value=map.get(name);
+			Variable var=null;
+			for(Variable variable:variables){
+				if(name.equals(variable.getLabel()) || name.equals(variable.getName())){
+					var=variable;
+					break;
+				}
+			}
+			if(var==null){
+				throw new RuleException("Variable ["+name+"] not exist.");
+			}
+			Datatype type=var.getType();
+			if(type.equals(Datatype.List) || type.equals(Datatype.Set) || type.equals(Datatype.Map)){
+				continue;
+			}
+			value=type.convert(value);
+			Utils.setObjectProperty(obj, var.getName(), value);
+		}
+	}
+	
+	
+	
+	@SuppressWarnings({ "unchecked"})
+	public void doTest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+		String data=req.getParameter("data");
+		ObjectMapper mapper=new ObjectMapper();
+		List<Map<String,Object>> list=mapper.readValue(data, ArrayList.class);
+		List<VariableCategory> variableCategories=mapToVariableCategories(list);
+		Map<VariableCategory,Object> facts=new HashMap<VariableCategory,Object>();
+		for(VariableCategory vc:variableCategories){
+			String clazz=vc.getClazz();
+			Object entity=null;
+			if(vc.getName().equals(VariableCategory.PARAM_CATEGORY)){
+				entity=new HashMap<String,Object>();
+			}else{
+				entity=new GeneralEntity(clazz);
+			}
+			for(Variable var:vc.getVariables()){
+				buildObject(entity, var);				
+			}
+			facts.put(vc,entity);
+		}
+		String flowId=req.getParameter("flowId");
+		long start=System.currentTimeMillis();
+		KnowledgeBase knowledgeBase=(KnowledgeBase)httpSessionKnowledgeCache.get(req, KB_KEY);
+		if(knowledgeBase==null){
+			knowledgeBase=buildKnowledgeBase(req);
+		}
+		KnowledgePackage knowledgePackage=knowledgeBase.getKnowledgePackage();
+		KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
+		Map<String,Object> parameters=null;
+		for(Object obj:facts.values()){
+			if(!(obj instanceof GeneralEntity) && (obj instanceof HashMap)){
+				parameters=(Map<String,Object>)obj;
+			}else{
+				session.insert(obj);				
+			}
+		}
+		ExecutionResponse response=null;
+		if(StringUtils.isNotEmpty(flowId)){
+			if(parameters!=null){
+				response=session.startProcess(flowId,parameters);
+			}else{
+				response=session.startProcess(flowId);
+			}
+		}else{
+			if(parameters==null){
+				response=session.fireRules();			
+			}else{
+				response=session.fireRules(parameters);						
+			}
+		}
+		for(VariableCategory vc:facts.keySet()){
+			Object obj=facts.get(vc);
+			if(obj==null){
+				continue;
+			}
+			if(obj instanceof Map && !(obj instanceof GeneralEntity)){
+				obj=session.getParameters();
+			}
+			for(Variable var:vc.getVariables()){
+				buildVariableValue(obj, var);
+			}
+		}
+		long end=System.currentTimeMillis();
+		long elapse=end-start;
+		ExecutionResponseImpl res=(ExecutionResponseImpl)response;
+		List<RuleInfo> firedRules=res.getFiredRules();
+		List<RuleInfo> matchedRules=res.getMatchedRules();
+		StringBuffer sb=new StringBuffer();
+		sb.append("耗时:"+elapse+"ms");
+		if(StringUtils.isEmpty(flowId)){
+			sb.append(",");
+			sb.append("匹配的规则共"+matchedRules.size()+"个");
+			if(matchedRules.size()>0){
+				buildRulesName(matchedRules, sb);				
+			}
+			sb.append(";");
+			sb.append("触发的规则共"+firedRules.size()+"个");
+			buildRulesName(firedRules, sb);
+		}
+		Map<String,Object> resultMap=new HashMap<String,Object>();
+		resultMap.put("info", sb.toString());
+		resultMap.put("data", variableCategories);
+		writeObjectToJson(resp, resultMap);
+	}
+	
+	private void buildObject(Object obj,Variable var){
+		String name=var.getName();
+		if(name.indexOf(".")!=-1){
+			instanceChildObject(obj,name);
+		}
+		String defaultValue=var.getDefaultValue();
+		if(StringUtils.isBlank(defaultValue)){
+			return;
+		}
+		Datatype type=var.getType();
+		if(type.equals(Datatype.List)){
+			Utils.setObjectProperty(obj, name, buildList(defaultValue));
+		}else if(type.equals(Datatype.Set)){
+			Utils.setObjectProperty(obj, name, buildSet(defaultValue));
+		}else if(type.equals(Datatype.Map)){
+			return;
+		}else{
+			Object value=type.convert(defaultValue);
+			Utils.setObjectProperty(obj, name, value);
+		}
+	}
+	
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	private List<GeneralEntity> buildList(String value){
+		try {
+			List<GeneralEntity> result=new ArrayList<GeneralEntity>();
+			ObjectMapper mapper=new ObjectMapper();
+			Map<String,Object> map=mapper.readValue(value, HashMap.class);
+			if(map.containsKey("rows")){
+				List<Object> list=(List<Object>)map.get("rows");
+				for(Object obj:list){
+					if(obj instanceof Map){
+						GeneralEntity entity=new GeneralEntity((String)map.get("type"));
+						entity.putAll((Map)obj);
+						result.add(entity);
+					}
+				}
+				return result;
+			}else{
+				return null;
+			}
+		} catch (Exception e) {
+			throw new RuleException(e);
+		}
+	}
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	private Set<GeneralEntity> buildSet(String value){
+		try {
+			Set<GeneralEntity> result=new HashSet<GeneralEntity>();
+			ObjectMapper mapper=new ObjectMapper();
+			Map<String,Object> map=mapper.readValue(value, HashMap.class);
+			if(map.containsKey("rows")){
+				List<Object> list=(List<Object>)map.get("rows");
+				for(Object obj:list){
+					if(obj instanceof Map){
+						GeneralEntity entity=new GeneralEntity((String)map.get("type"));
+						entity.putAll((Map)obj);
+						result.add(entity);
+					}
+				}
+				return result;
+			}else{
+				return null;
+			}
+		} catch (Exception e) {
+			throw new RuleException(e);
+		}
+	}
+	
+	private void instanceChildObject(Object obj,String propertyName){
+		int pointIndex=propertyName.indexOf(".");
+		if(pointIndex==-1){
+			return;
+		}
+		String name=propertyName.substring(0,pointIndex);
+		propertyName=propertyName.substring(pointIndex+1);
+		try {
+			Object instance=PropertyUtils.getProperty(obj, name);
+			if(instance!=null){
+				instanceChildObject(instance,propertyName);
+				return;
+			}
+			Object targetEntity=new GeneralEntity(name);
+			PropertyUtils.setProperty(obj, name, targetEntity);
+			instanceChildObject(targetEntity,propertyName);
+		} catch (Exception e) {
+			throw new RuleException(e);
+		}
+	}
+	
+
+	private void buildRulesName(List<RuleInfo> firedRules, StringBuffer sb) {
+		sb.append(":");
+		int i=0;
+		for(RuleInfo rule:firedRules){
+			if(i>0){
+				sb.append(",");
+			}
+			sb.append(rule.getName());
+			i++;
+		}
+	}
+	
+	private void buildVariableValue(Object object,Variable var){
+		String name=var.getName();
+		Object value=Utils.getObjectProperty(object, name);
+		if(value!=null){
+			Datatype type=var.getType();
+			if(type.equals(Datatype.List) || type.equals(Datatype.Set)){
+				//var.setDefaultValue(value.toString());								
+			}else{
+				String str=type.convertObjectToString(value);
+				var.setDefaultValue(str);				
+			}
+		}
+	}
+
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+	
+	public void setKnowledgeBuilder(KnowledgeBuilder knowledgeBuilder) {
+		this.knowledgeBuilder = knowledgeBuilder;
+	}
+	public void setHttpSessionKnowledgeCache(
+			HttpSessionKnowledgeCache httpSessionKnowledgeCache) {
+		this.httpSessionKnowledgeCache = httpSessionKnowledgeCache;
+	}
+	
+	@Override
+	public String url() {
+		return "/packageeditor";
+	}
+}

+ 58 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/respackage/SessionObject.java

@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.respackage;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Jacky.gao
+ * @since 2017820
+ */
+public class SessionObject {
+	private long start;
+	private static final long MILLISECOND=1200000;//default expired time is 20 minutes.
+	private Map<String,Object> map=new HashMap<String,Object>();
+	public SessionObject() {
+		this.start=System.currentTimeMillis();
+	}
+	public void put(String key,Object obj){
+		this.start=System.currentTimeMillis();
+		if(map.containsKey(key)){
+			map.remove(key);
+		}
+		map.put(key, obj);
+	}
+	
+	public Object get(String key){
+		this.start=System.currentTimeMillis();
+		return map.get(key);
+	}
+	
+	public void remove(String key){
+		this.start=System.currentTimeMillis();
+		map.remove(key);
+	}
+	
+	public boolean isExpired(){
+		long end=System.currentTimeMillis();
+		long value=end-start;
+		if(value>=MILLISECOND){
+			return true;
+		}
+		return false;
+	}
+}

+ 63 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/ruleset/RuleSetServletEditorHandler.java

@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.ruleset;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+
+/**
+ * @author Jacky.gao
+ * @since 201681
+ */
+public class RuleSetServletEditorHandler extends RenderPageServletHandler{
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			String file=req.getParameter("file");
+			file=Utils.decodeURL(file);
+			String project = buildProjectNameFromFile(file);
+			if(project!=null){
+				context.put("project", project);
+			}
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/ruleset-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	@Override
+	public String url() {
+		return "/ruleseteditor";
+	}
+	
+}

+ 63 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/scorecard/ScorecardEditorServletHandler.java

@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.scorecard;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+
+/**
+ * @author Jacky.gao
+ * @since 2016918
+ */
+public class ScorecardEditorServletHandler extends RenderPageServletHandler {
+
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			String file=req.getParameter("file");
+			String project = buildProjectNameFromFile(file);
+			if(project!=null){
+				context.put("project", project);
+			}
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/scorecard-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	
+
+	@Override
+	public String url() {
+		return "/scorecardeditor";
+	}
+}

+ 60 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/scriptdecisiontable/ScriptDecisiontableEditorServletHandler.java

@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.scriptdecisiontable;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+
+/**
+ * @author Jacky.gao
+ * @since 201681
+ */
+public class ScriptDecisiontableEditorServletHandler extends RenderPageServletHandler{
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			String file=req.getParameter("file");
+			String project = buildProjectNameFromFile(file);
+			if(project!=null){
+				context.put("project", project);
+			}
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/scriptdecisiontable-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	@Override
+	public String url() {
+		return "/scriptdecisiontableeditor";
+	}
+}

+ 110 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/ul/ULEditorServletHandler.java

@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.ul;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import com.bstek.urule.Utils;
+import com.bstek.urule.builder.ResourceLibraryBuilder;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.dsl.DSLRuleSetBuilder;
+import com.bstek.urule.model.library.ResourceLibrary;
+import com.bstek.urule.model.rule.RuleSet;
+
+/**
+ * @author Jacky.gao
+ * @since 201681
+ */
+public class ULEditorServletHandler extends RenderPageServletHandler{
+	private DSLRuleSetBuilder dslRuleSetBuilder;
+	private ResourceLibraryBuilder resourceLibraryBuilder;
+	private RepositoryService repositoryService;
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			String file=req.getParameter("file");
+			String project = buildProjectNameFromFile(file);
+			if(project!=null){
+				context.put("project", project);
+			}
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/ul-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	public void loadUL(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String file=req.getParameter("file");
+		file=Utils.decodeURL(file);
+		OutputStream outputStream=resp.getOutputStream();
+		String version=req.getParameter("version");
+		InputStream inputStream=null;
+		if(StringUtils.isEmpty(version)){
+			inputStream=repositoryService.readFile(file,null);
+		}else{
+			inputStream=repositoryService.readFile(file,version);			
+		}
+		try{
+			IOUtils.copy(inputStream, outputStream);
+		}finally{
+			outputStream.close();
+			inputStream.close();
+		}
+	}
+	public void loadULLibs(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String content = req.getParameter("content");
+		RuleSet ruleSet=dslRuleSetBuilder.build(content);
+		ResourceLibrary library=resourceLibraryBuilder.buildResourceLibrary(ruleSet.getLibraries());
+		writeObjectToJson(resp, library);
+	}
+	
+	public void setDslRuleSetBuilder(DSLRuleSetBuilder dslRuleSetBuilder) {
+		this.dslRuleSetBuilder = dslRuleSetBuilder;
+	}
+	public void setResourceLibraryBuilder(ResourceLibraryBuilder resourceLibraryBuilder) {
+		this.resourceLibraryBuilder = resourceLibraryBuilder;
+	}
+	
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+	
+	@Override
+	public String url() {
+		return "/uleditor";
+	}
+	
+}

+ 129 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/variable/VariableEditorServletHandler.java

@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.variable;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.io.IOUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+import com.bstek.urule.ClassUtils;
+import com.bstek.urule.console.servlet.RenderPageServletHandler;
+import com.bstek.urule.model.library.Datatype;
+import com.bstek.urule.model.library.variable.Act;
+import com.bstek.urule.model.library.variable.Variable;
+
+/**
+ * @author Jacky.gao
+ * @since 201663
+ */
+public class VariableEditorServletHandler extends RenderPageServletHandler {
+
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String method=retriveMethod(req);
+		if(method!=null){
+			invokeMethod(method, req, resp);
+		}else{
+			VelocityContext context = new VelocityContext();
+			context.put("contextPath", req.getContextPath());
+			resp.setContentType("text/html");
+			resp.setCharacterEncoding("utf-8");
+			Template template=ve.getTemplate("html/variable-editor.html","utf-8");
+			PrintWriter writer=resp.getWriter();
+			template.merge(context, writer);
+			writer.close();
+		}
+	}
+	
+	public void importXml(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		DiskFileItemFactory factory = new DiskFileItemFactory();
+		ServletContext servletContext = req.getSession().getServletContext();
+		File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
+		factory.setRepository(repository);
+		ServletFileUpload upload = new ServletFileUpload(factory);
+		InputStream inputStream=null;
+		try {
+			List<FileItem> items = upload.parseRequest(req);
+			if(items.size()!=1){
+				throw new ServletException("Upload xml file is invalid.");
+			}
+			FileItem item=items.get(0);
+			inputStream=item.getInputStream();
+			String xmlContent=IOUtils.toString(inputStream, "utf-8");
+			List<Variable> variables=new ArrayList<Variable>();
+			Document doc=DocumentHelper.parseText(xmlContent);
+			Element root=doc.getRootElement();
+			String clazz=root.attributeValue("clazz");
+			for(Object obj:root.elements()){
+				if(obj==null || !(obj instanceof Element)){
+					continue;
+				}
+				Element ele=(Element)obj;
+				Variable var=new Variable();
+				var.setAct(Act.InOut);
+				var.setDefaultValue(ele.attributeValue("defaultValue"));
+				var.setLabel(ele.attributeValue("label"));
+				var.setName(ele.attributeValue("name"));
+				var.setType(Datatype.valueOf(ele.attributeValue("type")));
+				variables.add(var);
+			}
+			Map<String,Object> result=new HashMap<String,Object>();
+			result.put("clazz", clazz);
+			result.put("variables", variables);
+			writeObjectToJson(resp, result);
+		} catch (Exception e) {
+			throw new ServletException(e);
+		} finally {
+			IOUtils.closeQuietly(inputStream);
+		}
+	}
+	
+	public void generateFields(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String clazz=req.getParameter("clazz");
+		try {
+			List<Variable> variables=ClassUtils.classToVariables(Class.forName(clazz));
+			writeObjectToJson(resp, variables);
+		} catch (ClassNotFoundException e) {
+			throw new ServletException(e);
+		}
+	}
+	
+
+	@Override
+	public String url() {
+		return "/variableeditor";
+	}
+}

+ 170 - 0
urule-console/src/main/java/com/bstek/urule/console/servlet/xml/XmlServletHandler.java

@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright 2017 Bstek
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package com.bstek.urule.console.servlet.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import com.bstek.urule.RuleException;
+import com.bstek.urule.Utils;
+import com.bstek.urule.console.repository.RepositoryResourceProvider;
+import com.bstek.urule.console.repository.RepositoryService;
+import com.bstek.urule.console.servlet.WriteJsonServletHandler;
+import com.bstek.urule.model.library.action.ActionLibrary;
+import com.bstek.urule.model.library.action.SpringBean;
+import com.bstek.urule.parse.deserializer.ActionLibraryDeserializer;
+import com.bstek.urule.parse.deserializer.ConstantLibraryDeserializer;
+import com.bstek.urule.parse.deserializer.DecisionTableDeserializer;
+import com.bstek.urule.parse.deserializer.DecisionTreeDeserializer;
+import com.bstek.urule.parse.deserializer.Deserializer;
+import com.bstek.urule.parse.deserializer.ParameterLibraryDeserializer;
+import com.bstek.urule.parse.deserializer.RuleSetDeserializer;
+import com.bstek.urule.parse.deserializer.ScriptDecisionTableDeserializer;
+import com.bstek.urule.parse.deserializer.VariableLibraryDeserializer;
+import com.bstek.urule.runtime.BuiltInActionLibraryBuilder;
+
+/**
+ * @author Jacky.gao
+ * @since 201663
+ */
+public class XmlServletHandler extends WriteJsonServletHandler implements ApplicationContextAware{
+	private RepositoryService repositoryService;
+	private BuiltInActionLibraryBuilder builtInActionLibraryBuilder;
+	protected List<Deserializer<?>> deserializers=new ArrayList<Deserializer<?>>();
+	@Override
+	public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		String methodName=retriveMethod(req);
+		if(methodName!=null){
+			invokeMethod(methodName, req, resp);
+		}else{
+			//default load xml
+			loadXml(req, resp);
+		}
+	}
+	
+	public void loadXml(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		List<Object> result=new ArrayList<Object>();
+		String files=req.getParameter("files");
+		boolean isaction=false;
+		if(files!=null){
+			if(files.startsWith("builtinactions")){
+				isaction=true;
+			}else{
+				files=Utils.decodeURL(files);
+				String[] paths=files.split(";");
+				for(String path:paths){
+					path=Utils.toUTF8(path);
+					if(path.startsWith(RepositoryResourceProvider.JCR)){
+						path=path.substring(4,path.length());					
+					}
+					String[] subpaths=path.split(",");
+					path=subpaths[0];
+					String version=null;
+					if(subpaths.length==2){
+						version=subpaths[1];
+					}
+					InputStream inputStream=null;
+					if(StringUtils.isEmpty(version)){
+						inputStream=repositoryService.readFile(path,null);
+					}else{
+						inputStream=repositoryService.readFile(path,version);			
+					}
+					try{
+						Element element=parseXml(inputStream);
+						for(Deserializer<?> des:deserializers){
+							if(des.support(element)){
+								result.add(des.deserialize(element));
+								if(des instanceof ActionLibraryDeserializer){
+									isaction=true;
+								}
+								break;
+							}
+						}
+					}finally{
+						inputStream.close();
+					}
+				}
+			}
+		}
+		if(isaction){
+			List<SpringBean> beans=builtInActionLibraryBuilder.getBuiltInActions();
+			if(beans.size()>0){
+				ActionLibrary al=new ActionLibrary();
+				al.setSpringBeans(beans);
+				result.add(al);
+			}
+		}
+		writeObjectToJson(resp,result);
+	}
+	
+	protected Element parseXml(InputStream stream){
+		SAXReader reader=new SAXReader();
+		Document document;
+		try {
+			document = reader.read(stream);
+			Element root=document.getRootElement();
+			return root;
+		} catch (DocumentException e) {
+			throw new RuleException(e);
+		}
+	}
+
+	@Override
+	public String url() {
+		return "/xml";
+	}
+	
+	public void setBuiltInActionLibraryBuilder(
+			BuiltInActionLibraryBuilder builtInActionLibraryBuilder) {
+		this.builtInActionLibraryBuilder = builtInActionLibraryBuilder;
+	}
+	public void setRepositoryService(RepositoryService repositoryService) {
+		this.repositoryService = repositoryService;
+	}
+	public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
+		ActionLibraryDeserializer actionLibraryDeserializer=(ActionLibraryDeserializer)applicationContext.getBean(ActionLibraryDeserializer.BEAN_ID);
+		VariableLibraryDeserializer variableLibraryDeserializer=(VariableLibraryDeserializer)applicationContext.getBean(VariableLibraryDeserializer.BEAN_ID);
+		ConstantLibraryDeserializer constantLibraryDeserializer=(ConstantLibraryDeserializer)applicationContext.getBean(ConstantLibraryDeserializer.BEAN_ID);
+		RuleSetDeserializer ruleSetDeserializer=(RuleSetDeserializer)applicationContext.getBean(RuleSetDeserializer.BEAN_ID);
+		DecisionTableDeserializer decisionTableDeserializer=(DecisionTableDeserializer)applicationContext.getBean(DecisionTableDeserializer.BEAN_ID);
+		ScriptDecisionTableDeserializer scriptDecisionTableDeserializer=(ScriptDecisionTableDeserializer)applicationContext.getBean(ScriptDecisionTableDeserializer.BEAN_ID);
+		DecisionTreeDeserializer decisionTreeDeserializer=(DecisionTreeDeserializer)applicationContext.getBean(DecisionTreeDeserializer.BEAN_ID);
+		ParameterLibraryDeserializer parameterLibraryDeserializer=(ParameterLibraryDeserializer)applicationContext.getBean(ParameterLibraryDeserializer.BEAN_ID);
+		deserializers.add(actionLibraryDeserializer);
+		deserializers.add(variableLibraryDeserializer);
+		deserializers.add(constantLibraryDeserializer);
+		deserializers.add(ruleSetDeserializer);
+		deserializers.add(decisionTableDeserializer);
+		deserializers.add(scriptDecisionTableDeserializer);
+		deserializers.add(decisionTreeDeserializer);
+		deserializers.add(parameterLibraryDeserializer);
+	}
+}

+ 17 - 0
urule-console/src/main/resources/html/action-editor.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>动作编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/actionEditor.bundle.js"></script>
+</body>
+</html>

+ 17 - 0
urule-console/src/main/resources/html/client-config-editor.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>客户端推送配置</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/clientConfigEditor.bundle.js"></script>
+</body>
+</html>

+ 17 - 0
urule-console/src/main/resources/html/constant-editor.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>常量编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/constantEditor.bundle.js"></script>
+</body>
+</html>

+ 18 - 0
urule-console/src/main/resources/html/decisiontable-editor.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>决策表编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body style='font-size:12px;overflow: auto'>
+<div id='container'></div>
+<div id='dialogContainer'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+	window._project="${project}";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/decisionTableEditor.bundle.js"></script>
+</body>
+</html>

+ 18 - 0
urule-console/src/main/resources/html/decisiontree-editor.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>决策树编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+  <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body style='font-size:12px'>
+<div id='container'></div>
+<div id='dialogContainer'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+	window._project="${project}";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/decisionTreeEditor.bundle.js"></script>
+</body>
+</html>

+ 19 - 0
urule-console/src/main/resources/html/frame.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>${title}</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrapValidator.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+	window._welcomePage="${welcomePage}";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/frame.bundle.js"></script>
+</body>
+</html>

+ 18 - 0
urule-console/src/main/resources/html/package-editor.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>知识包编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrapValidator.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/packageEditor.bundle.js"></script>
+</body>
+</html>

+ 17 - 0
urule-console/src/main/resources/html/parameter-editor.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>参数编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/parameterEditor.bundle.js"></script>
+</body>
+</html>

+ 17 - 0
urule-console/src/main/resources/html/permission-config-editor.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>权限配置</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/permissionConfigEditor.bundle.js"></script>
+</body>
+</html>

+ 24 - 0
urule-console/src/main/resources/html/rete-diagram.html

@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<meta http-equiv="pragma" content="no-cache"> 
+<meta http-equiv="expires" content="0">
+<title>RETE树展示</title>
+ <link rel="stylesheet" href="${contextPath}/urule/res/urule-asserts/css/bootstrap.min.css">
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/raphael.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/retediagram.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+	$(document).ready(function(){
+		var files="${files}";
+		drawReteDiagram('container',files);
+	});
+</script>
+</body>
+</html>

+ 17 - 0
urule-console/src/main/resources/html/rule-flow-designer.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>决策流设计器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+  <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+	window._project="${project}";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/flowDesigner.bundle.js"></script>
+</body>
+</html>

+ 19 - 0
urule-console/src/main/resources/html/ruleset-editor.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>决策集编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery-ui.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+  <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body style='font-size:12px'>
+<div id='container'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+	window._project="${project}";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/ruleSetEditor.bundle.js"></script>
+</body>
+</html>

+ 21 - 0
urule-console/src/main/resources/html/scorecard-editor.html

@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>评分卡编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootstrap.min.js"></script>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body style="margin:3px">
+<div id='toolbarContainer'></div>
+<div id='tableContainer' style="margin-top:5px;margin-left:3px"></div>
+<div id='actionContainer'></div>
+<div id="dialogContainer"></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+	window._project="${project}";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/scoreCardTable.bundle.js"></script>
+</body>
+</html>

+ 18 - 0
urule-console/src/main/resources/html/scriptdecisiontable-editor.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>脚本式决策表编辑器</title>
+ <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/jquery.min.js"></script>
+  <script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/venderjs/bootbox.min.js"></script>
+</head>
+<body style='font-size:12px'>
+<div id='container'></div>
+<div id='dialogContainer'></div>
+<script type="text/javascript">
+	window._server="${contextPath}/urule";
+	window._project="${project}";
+</script>
+<script type="text/javascript" src="${contextPath}/urule/res/urule-asserts/js/scriptDecisionTableEditor.bundle.js"></script>
+</body>
+</html>

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