├── .DS_Store ├── .buildpath ├── .classpath ├── .gitignore ├── .project ├── .settings ├── .jsdtscope ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.core.prefs ├── org.eclipse.ltk.core.refactoring.prefs ├── org.eclipse.m2e.core.prefs ├── org.eclipse.vjet.eclipse.core.prefs ├── org.eclipse.wst.common.component ├── org.eclipse.wst.common.project.facet.core.xml ├── org.eclipse.wst.jsdt.ui.superType.container ├── org.eclipse.wst.jsdt.ui.superType.name ├── org.eclipse.wst.validation.prefs └── org.eclipse.wst.ws.service.policy.prefs ├── logs ├── common-default.log └── common-error.log ├── pom.xml └── src ├── .DS_Store ├── main ├── .DS_Store ├── java │ ├── .DS_Store │ └── com │ │ ├── .DS_Store │ │ └── huxuemin │ │ ├── .DS_Store │ │ └── xblog │ │ ├── .DS_Store │ │ ├── application │ │ ├── ArticleService.java │ │ └── UserService.java │ │ ├── auth │ │ ├── AuthFilter.java │ │ ├── AuthPolicy.java │ │ ├── BlogConfigTest.java │ │ └── PublishAuthCheck.java │ │ ├── config │ │ ├── RootConfig.java │ │ └── XBlogWebAppInitializer.java │ │ ├── database │ │ ├── ConnectionAdapter.java │ │ ├── ConnectionException.java │ │ ├── ConnectionPool.java │ │ ├── DBConnectionFactory.java │ │ ├── ITable.java │ │ ├── MySqlDBManager.java │ │ ├── mapper │ │ │ ├── BaseMapper.java │ │ │ ├── ColumnAnnotationProcesser.java │ │ │ ├── ColumnOneToManyMap.java │ │ │ ├── ColumnOneToOneMap.java │ │ │ ├── Criteria.java │ │ │ ├── CriteriaOperator.java │ │ │ ├── DomainObjectMap.java │ │ │ ├── MapperRegister.java │ │ │ ├── OneToManyColumn.java │ │ │ ├── OneToManyDomainObject.java │ │ │ ├── OneToOneColumn.java │ │ │ ├── OneToOneDomainObject.java │ │ │ ├── PrimaryKeyColumn.java │ │ │ ├── QueryObject.java │ │ │ ├── SqlTransactionException.java │ │ │ ├── Table.java │ │ │ ├── TableAnnotationProcesser.java │ │ │ └── TableMap.java │ │ └── table │ │ │ ├── ArticleTable.java │ │ │ ├── DiscussTable.java │ │ │ ├── RoleAuthTable.java │ │ │ ├── RolesTable.java │ │ │ ├── UserPrivateInfoTable.java │ │ │ ├── UserPublicInfoTable.java │ │ │ ├── UserRolesTable.java │ │ │ └── UserTable.java │ │ ├── domain │ │ ├── article │ │ │ ├── Article.java │ │ │ ├── ArticleFactory.java │ │ │ ├── ArticleNotFoundException.java │ │ │ ├── Discuss.java │ │ │ ├── DiscussComparator.java │ │ │ └── DiscussNotFoundException.java │ │ ├── repository │ │ │ ├── ArticleRepository.java │ │ │ ├── IRepository.java │ │ │ ├── RepositoryRegister.java │ │ │ ├── RoleRepository.java │ │ │ ├── UnitOfWork.java │ │ │ └── UserRepository.java │ │ └── user │ │ │ ├── Role.java │ │ │ ├── User.java │ │ │ ├── UserFactory.java │ │ │ ├── UserNotFoundException.java │ │ │ ├── UserPrivateInfo.java │ │ │ ├── UserPublicInfo.java │ │ │ └── UserVerifyFailedException.java │ │ ├── infrastructure │ │ ├── AuthConstant.java │ │ ├── AuthException.java │ │ ├── DomainObject.java │ │ ├── DoubleNodeStruct.java │ │ ├── ErrorMessage.java │ │ ├── RegexConstant.java │ │ ├── RigheNodeStruct.java │ │ ├── SessionConstant.java │ │ ├── SuccessMessage.java │ │ ├── dtos │ │ │ ├── ArticleDTO.java │ │ │ ├── ArticleSummaryDTO.java │ │ │ ├── ArticleSummaryDTOList.java │ │ │ ├── DiscussDTO.java │ │ │ ├── DiscussDTOList.java │ │ │ ├── DisplayNameDTO.java │ │ │ ├── PageDTO.java │ │ │ └── UserInfoDTO.java │ │ └── tools │ │ │ ├── ClasspathPackageScanner.java │ │ │ ├── CustomDateSerializer.java │ │ │ ├── HTMLEscape.java │ │ │ ├── IDCreateFactory.java │ │ │ ├── JSONTools.java │ │ │ ├── MD5Tools.java │ │ │ ├── StringUtil.java │ │ │ └── praseTools.java │ │ └── web │ │ ├── ContextManager.java │ │ ├── ObjectHttpMessageConverter.java │ │ ├── WebConfig.java │ │ ├── restAPI │ │ ├── ArticleAPI.java │ │ ├── LoginAPI.java │ │ └── UserAPI.java │ │ └── viewController │ │ ├── ApiController.java │ │ ├── ArticleController.java │ │ ├── HomeController.java │ │ ├── LoginController.java │ │ ├── ManagePageController.java │ │ ├── RegisterController.java │ │ └── UserController.java ├── resources │ └── log4j.xml └── webapp │ ├── .DS_Store │ ├── .idea │ ├── modules.xml │ ├── webapp.iml │ └── workspace.xml │ ├── WEB-INF │ ├── .DS_Store │ ├── views │ │ ├── 404.html │ │ ├── api.html │ │ ├── article.html │ │ ├── article │ │ │ └── templet.html │ │ ├── index.html │ │ ├── login.html │ │ ├── manage.html │ │ ├── password.html │ │ ├── publish.html │ │ ├── register.html │ │ └── userinfo.html │ └── web.xml │ ├── css │ ├── bootstrap-theme.css │ ├── bootstrap-theme.css.map │ ├── bootstrap-theme.min.css │ ├── bootstrap-theme.min.css.map │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ ├── bootstrap.min.css.map │ ├── font-awesome.css │ └── xblog.css │ ├── font │ └── fontawesome-webfont.woff │ ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 │ ├── glyphicons-halflings.png │ ├── images │ ├── Favicon_big.png │ ├── Home.ico │ └── Main.jpg │ └── js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── default-main.js │ ├── jquery.js │ └── npm.js └── test ├── .DS_Store └── java └── com └── huxuemin └── xblog └── test └── web ├── ArticleServiceTest.java └── RestApiWebAppContextTest.java /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/.DS_Store -------------------------------------------------------------------------------- /.buildpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | xBlog 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.vjet.eclipse.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.wst.jsdt.core.javascriptValidator 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.wst.common.project.facet.core.builder 25 | 26 | 27 | 28 | 29 | org.eclipse.wst.validation.validationbuilder 30 | 31 | 32 | 33 | 34 | org.eclipse.m2e.core.maven2Builder 35 | 36 | 37 | 38 | 39 | 40 | org.eclipse.vjet.core.nature 41 | org.eclipse.wst.common.project.facet.core.nature 42 | org.eclipse.wst.jsdt.core.jsNature 43 | org.eclipse.jem.workbench.JavaEMFNature 44 | org.eclipse.m2e.core.maven2Nature 45 | org.eclipse.jdt.core.javanature 46 | org.eclipse.wst.common.modulecore.ModuleCoreNature 47 | 48 | 49 | -------------------------------------------------------------------------------- /.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /.settings/org.eclipse.ltk.core.refactoring.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /.settings/org.eclipse.vjet.eclipse.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | initialized_project_from_v4classpath=true 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.component: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.container: -------------------------------------------------------------------------------- 1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.name: -------------------------------------------------------------------------------- 1 | Window -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.validation.prefs: -------------------------------------------------------------------------------- 1 | disabled=06target 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.ws.service.policy.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.wst.ws.service.policy.projectEnabled=false 3 | -------------------------------------------------------------------------------- /logs/common-default.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/logs/common-default.log -------------------------------------------------------------------------------- /logs/common-error.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/logs/common-error.log -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.huxuemin 5 | xBlog 6 | war 7 | 0.0.3-SNAPSHOT 8 | xBlog Maven Webapp 9 | http://maven.apache.org 10 | 11 | 5.1.39 12 | UTF-8 13 | 4.3.4.RELEASE 14 | 4.12 15 | 1.7.21 16 | 17 | 18 | 19 | junit 20 | junit 21 | ${junit.version} 22 | test 23 | 24 | 25 | javax.servlet 26 | javax.servlet-api 27 | 3.0.1 28 | 29 | 30 | com.google.code.gson 31 | gson 32 | 2.2.2 33 | 34 | 35 | mysql 36 | mysql-connector-java 37 | ${mysql.version} 38 | 39 | 40 | org.springframework 41 | spring-core 42 | ${spring.version} 43 | 44 | 45 | commons-logging 46 | commons-logging 47 | 48 | 49 | 50 | 51 | org.springframework 52 | spring-context 53 | ${spring.version} 54 | 55 | 56 | com.github.stefanbirkner 57 | system-rules 58 | 1.16.0 59 | 60 | 61 | org.springframework 62 | spring-test 63 | ${spring.version} 64 | 65 | 66 | org.springframework 67 | spring-aspects 68 | ${spring.version} 69 | 70 | 71 | org.springframework 72 | spring-webmvc 73 | ${spring.version} 74 | 75 | 76 | org.apache.commons 77 | commons-lang3 78 | 3.5 79 | 80 | 81 | com.fasterxml.jackson.core 82 | jackson-databind 83 | 2.8.5 84 | 85 | 86 | 87 | org.slf4j 88 | jcl-over-slf4j 89 | ${slf4j.version} 90 | 91 | 92 | org.slf4j 93 | slf4j-api 94 | ${slf4j.version} 95 | 96 | 97 | org.slf4j 98 | slf4j-log4j12 99 | ${slf4j.version} 100 | 101 | 102 | log4j 103 | log4j 104 | 1.2.17 105 | 106 | 107 | 108 | xBlog 109 | compile 110 | 111 | 112 | org.apache.maven.plugins 113 | maven-compiler-plugin 114 | 3.1 115 | 116 | 1.8 117 | 1.8 118 | 119 | 120 | 121 | 122 | 123 | huxuemin 124 | www.huxuemin.com 125 | 126 | 127 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/.DS_Store -------------------------------------------------------------------------------- /src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/.DS_Store -------------------------------------------------------------------------------- /src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/java/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/java/com/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/java/com/huxuemin/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/java/com/huxuemin/xblog/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/application/UserService.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.application; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import com.huxuemin.xblog.domain.repository.RepositoryRegister; 9 | import com.huxuemin.xblog.domain.repository.UnitOfWork; 10 | import com.huxuemin.xblog.domain.user.User; 11 | import com.huxuemin.xblog.domain.user.UserFactory; 12 | import com.huxuemin.xblog.domain.user.UserNotFoundException; 13 | import com.huxuemin.xblog.domain.user.UserVerifyFailedException; 14 | import com.huxuemin.xblog.infrastructure.AuthConstant; 15 | import com.huxuemin.xblog.infrastructure.AuthException; 16 | import com.huxuemin.xblog.infrastructure.RegexConstant; 17 | import com.huxuemin.xblog.infrastructure.dtos.UserInfoDTO; 18 | 19 | @Service 20 | public class UserService { 21 | 22 | @Autowired 23 | ArticleService articleService; 24 | 25 | public boolean verify(String username, String password) throws UserVerifyFailedException { 26 | if (regexCheckUsername(username) && regexCheckPassword(password)) { 27 | User user = RepositoryRegister.getUserRepository().get(username); 28 | if (user != null && user.checkPassword(password)) { 29 | return true; 30 | } 31 | } 32 | throw new UserVerifyFailedException(); 33 | } 34 | 35 | public boolean manage(String username, String password) throws UserVerifyFailedException { 36 | if (regexCheckUsername(username) && regexCheckPassword(password)) { 37 | User user = RepositoryRegister.getUserRepository().get(username); 38 | if (user != null && user.checkPassword(password)) { 39 | if(user.hasAuth(AuthConstant.MANAGE_PAGE)){ 40 | return true; 41 | } 42 | } 43 | } 44 | throw new AuthException(AuthConstant.MANAGE_PAGE); 45 | } 46 | 47 | public void testPublish() { 48 | System.out.println("testPublish()"); 49 | articleService.publish("afsdf", "sfsadf", "admin", "admin123"); 50 | } 51 | 52 | public UserInfoDTO getUserInfo(String username, String password, String usernameforinfo) 53 | throws UserNotFoundException { 54 | if (regexCheckUsername(usernameforinfo)) { 55 | User usersinfo = RepositoryRegister.getUserRepository().get(usernameforinfo); 56 | if (usersinfo != null) { 57 | if (regexCheckUsername(username) && regexCheckPassword(password)) { 58 | User user = RepositoryRegister.getUserRepository().get(username); 59 | if (user.checkPassword(password)) { 60 | if (user.equals(usersinfo) || user.hasAuth(AuthConstant.USER_MANAGER)) { 61 | return UserFactory.createFullUserInfoDTO(usersinfo); 62 | } 63 | } 64 | } 65 | return UserFactory.createUserInfoDTO(usersinfo); 66 | } 67 | } 68 | throw new UserNotFoundException(); 69 | } 70 | 71 | public void modifyUserInfo(String username, String password, UserInfoDTO userInfoDTO) throws AuthException { 72 | if (regexCheckUsername(userInfoDTO.getUserName())) { 73 | User infoUser = RepositoryRegister.getUserRepository().get(userInfoDTO.getUserName()); 74 | if (regexCheckUsername(username) && regexCheckPassword(password)) { 75 | User user = RepositoryRegister.getUserRepository().get(username); 76 | if (user.checkPassword(password)) { 77 | if (user.equals(infoUser) || user.hasAuth(AuthConstant.USER_MANAGER)) { 78 | UnitOfWork.newCurrent(); 79 | UserFactory.modifyUserInfo(userInfoDTO); 80 | UnitOfWork.getCurrent().commit(); 81 | return; 82 | } 83 | } 84 | } 85 | } 86 | throw new AuthException(AuthConstant.USER_MANAGER); 87 | } 88 | 89 | public UserInfoDTO register(String username, String password) { 90 | if (regexCheckUsername(username) && regexCheckPassword(password)) { 91 | if (!RepositoryRegister.getUserRepository().isExistByPrimaryKey(username)) { 92 | UnitOfWork.newCurrent(); 93 | User user = UserFactory.createUser(username, password); 94 | RepositoryRegister.getUserRepository().add(user); 95 | UnitOfWork.getCurrent().commit(); 96 | return UserFactory.createUserInfoDTO(user); 97 | } 98 | } 99 | throw new UserNotFoundException(); 100 | } 101 | 102 | public String getUserDisplayName(String username) throws UserNotFoundException { 103 | User user = RepositoryRegister.getUserRepository().get(username); 104 | if (user != null) { 105 | return user.getUserDisplayName(); 106 | } 107 | throw new UserNotFoundException(); 108 | } 109 | 110 | public boolean hasAuth(String username, AuthConstant auth) { 111 | boolean result = false; 112 | User user = RepositoryRegister.getUserRepository().get(username); 113 | if (user != null && user.hasAuth(auth)) { 114 | result = true; 115 | } 116 | return result; 117 | } 118 | 119 | public boolean hasEditUserInfoAuth(String username, String password, String targetUser) { 120 | if (regexCheckUsername(targetUser)) { 121 | User usersinfo = RepositoryRegister.getUserRepository().get(targetUser); 122 | if (usersinfo != null && regexCheckUsername(username) && regexCheckPassword(password)) { 123 | User user = RepositoryRegister.getUserRepository().get(username); 124 | if (user!= null && user.checkPassword(password)) { 125 | if (user.equals(usersinfo) || user.hasAuth(AuthConstant.USER_MANAGER)) { 126 | return true; 127 | } 128 | } 129 | } 130 | } 131 | throw new AuthException(AuthConstant.USER_MANAGER); 132 | } 133 | 134 | public boolean changePassword(String username, String oldPassword, String newPassword){ 135 | boolean result = false; 136 | if (regexCheckUsername(username)) { 137 | User usersinfo = RepositoryRegister.getUserRepository().get(username); 138 | if (usersinfo != null && regexCheckPassword(oldPassword) && regexCheckPassword(newPassword)) { 139 | UnitOfWork.newCurrent(); 140 | result = usersinfo.changePassword(oldPassword, newPassword); 141 | UnitOfWork.getCurrent().commit(); 142 | } 143 | } 144 | return result; 145 | } 146 | 147 | private boolean regexCheckUsername(String username) { 148 | if (username != null) { 149 | return Pattern.compile(RegexConstant.USERNAME).matcher(username).matches(); 150 | } else { 151 | return false; 152 | } 153 | } 154 | 155 | private boolean regexCheckPassword(String password) { 156 | if (password != null) { 157 | return Pattern.compile(RegexConstant.PASSWORD).matcher(password).matches(); 158 | } else { 159 | return false; 160 | } 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/auth/AuthFilter.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.auth; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import javax.servlet.Filter; 8 | import javax.servlet.FilterChain; 9 | import javax.servlet.FilterConfig; 10 | import javax.servlet.ServletException; 11 | import javax.servlet.ServletRequest; 12 | import javax.servlet.ServletResponse; 13 | import javax.servlet.annotation.WebFilter; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | 17 | @WebFilter(urlPatterns = "/*") 18 | public class AuthFilter implements Filter { 19 | 20 | private List authPolicys; 21 | @Override 22 | public void init(FilterConfig filterConfig) throws ServletException { 23 | // TODO Auto-generated method stub 24 | // System.out.println("AuthFilter.init(FilterConfig filterConfig)"); 25 | authPolicys = new ArrayList(); 26 | authPolicys.add(new AuthPolicy("/xBlog/api/articles","post","put")); 27 | } 28 | 29 | @Override 30 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 31 | throws IOException, ServletException { 32 | // TODO Auto-generated method stub 33 | // System.out.println("AuthFilter.doFilter(ServletRequest request, ServletResponse response, FilterChain chain)"); 34 | if (!(request instanceof HttpServletRequest && response instanceof HttpServletResponse)) { 35 | throw new ServletException("non-Http request or response"); 36 | } 37 | HttpServletRequest httpRequest = (HttpServletRequest) request; 38 | for(int i = 0;i < authPolicys.size();i++){ 39 | if (authPolicys.get(i).isMatch(httpRequest)) { 40 | System.out.println("match"); 41 | } 42 | } 43 | System.out.println(httpRequest.getRequestURI()); 44 | chain.doFilter(request, response); 45 | } 46 | 47 | @Override 48 | public void destroy() { 49 | // TODO Auto-generated method stub 50 | // System.out.println("AuthFilter.destroy()"); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/auth/AuthPolicy.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.auth; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | 8 | public class AuthPolicy { 9 | public static final String METHOD_DELETE = "DELETE"; 10 | public static final String METHOD_HEAD = "HEAD"; 11 | public static final String METHOD_GET = "GET"; 12 | public static final String METHOD_OPTIONS = "OPTIONS"; 13 | public static final String METHOD_POST = "POST"; 14 | public static final String METHOD_PUT = "PUT"; 15 | public static final String METHOD_TRACE = "TRACE"; 16 | 17 | private static final String[] METHOD_CONSTANTS = { METHOD_DELETE, METHOD_HEAD, METHOD_GET, METHOD_OPTIONS, 18 | METHOD_POST, METHOD_PUT, METHOD_TRACE }; 19 | private static final int METHOD_NUM = METHOD_CONSTANTS.length; 20 | 21 | private List methodsPolicy = new ArrayList(); 22 | private String url; 23 | 24 | public AuthPolicy(String url, String... methods) { 25 | this.url = url; 26 | for (int i = 0; i < methods.length; i++) { 27 | addMethod(methods[i]); 28 | } 29 | } 30 | 31 | public void addMethod(String method) { 32 | String upMethod = method.toUpperCase(); 33 | if (isValid(upMethod)) { 34 | if (!this.methodsPolicy.contains(upMethod)) { 35 | this.methodsPolicy.add(upMethod); 36 | } 37 | } 38 | } 39 | 40 | public void removeMethod(String method) { 41 | String upMethod = method.toUpperCase(); 42 | if (isValid(upMethod)) { 43 | if (this.methodsPolicy.contains(upMethod)) { 44 | this.methodsPolicy.remove(upMethod); 45 | } 46 | } 47 | } 48 | 49 | private boolean isValid(String method) { 50 | for (int i = 0; i < METHOD_NUM; i++) { 51 | if (method.equals(METHOD_CONSTANTS[i])) { 52 | return true; 53 | } 54 | } 55 | return false; 56 | } 57 | 58 | public boolean isMatch(HttpServletRequest request) { 59 | if (request.getRequestURI().startsWith(url)) { 60 | for (int i = 0; i < methodsPolicy.size(); i++) { 61 | if (request.getMethod().equals(methodsPolicy.get(i))) { 62 | return true; 63 | } 64 | } 65 | } 66 | return false; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/auth/BlogConfigTest.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.auth; 2 | 3 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 | 5 | import com.huxuemin.xblog.application.ArticleService; 6 | import com.huxuemin.xblog.config.RootConfig; 7 | 8 | public class BlogConfigTest { 9 | 10 | public static void main(String[] args){ 11 | AnnotationConfigApplicationContext context = 12 | new AnnotationConfigApplicationContext(RootConfig.class); 13 | ArticleService articleS = context.getBean(ArticleService.class); 14 | articleS.publish("afsadf", "asfsdf", "admin", "admin1234"); 15 | context.close(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/auth/PublishAuthCheck.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.auth; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpSession; 5 | 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.springframework.web.context.request.RequestContextHolder; 9 | import org.springframework.web.context.request.ServletRequestAttributes; 10 | 11 | import com.huxuemin.xblog.infrastructure.SessionConstant; 12 | 13 | //@Aspect 14 | public class PublishAuthCheck { 15 | 16 | // @Pointcut("execution(** 17 | // com.huxuemin.xblog.application.ArticleService.publish(..))") 18 | // public void publishAuth() {} 19 | 20 | // @Around("publishAuth()") 21 | @Around("execution(* com.huxuemin.xblog.application.ArticleService.publish(..))") 22 | public void publishAuthCheck(ProceedingJoinPoint jp) { 23 | // HttpSession session = request.getSession(); 24 | // String loginid = (String) session.getAttribute("loginId"); 25 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) 26 | .getRequest(); 27 | HttpSession session = request.getSession(); 28 | System.out.println("publishAuthCheck(),loginId:" + session.getAttribute(SessionConstant.USERNAME)); 29 | try { 30 | jp.proceed(); 31 | } catch (Throwable e) { 32 | // TODO Auto-generated catch block 33 | e.printStackTrace(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/config/RootConfig.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.config; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.ComponentScan; 7 | import org.springframework.context.annotation.ComponentScan.Filter; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.annotation.EnableAspectJAutoProxy; 10 | import org.springframework.context.annotation.FilterType; 11 | import org.springframework.core.type.filter.RegexPatternTypeFilter; 12 | 13 | import com.huxuemin.xblog.auth.PublishAuthCheck; 14 | import com.huxuemin.xblog.config.RootConfig.WebPackage; 15 | import com.huxuemin.xblog.domain.repository.ArticleRepository; 16 | import com.huxuemin.xblog.domain.repository.RepositoryRegister; 17 | import com.huxuemin.xblog.domain.repository.RoleRepository; 18 | import com.huxuemin.xblog.domain.repository.UserRepository; 19 | 20 | @Configuration 21 | @ComponentScan(basePackages = { "com.huxuemin.xblog" }, excludeFilters = { 22 | @Filter(type = FilterType.CUSTOM, value = WebPackage.class) }) 23 | @EnableAspectJAutoProxy(proxyTargetClass=true) 24 | public class RootConfig { 25 | 26 | public static class WebPackage extends RegexPatternTypeFilter { 27 | public WebPackage() { 28 | super(Pattern.compile("com\\.huxuemin\\.xblog\\.web.*")); 29 | } 30 | } 31 | 32 | @Bean 33 | public ArticleRepository articleRepository() { 34 | return RepositoryRegister.getArticleRepository(); 35 | } 36 | 37 | @Bean 38 | public UserRepository userRepository() { 39 | return RepositoryRegister.getUserRepository(); 40 | } 41 | 42 | @Bean 43 | public RoleRepository roleRepository() { 44 | return RepositoryRegister.getRoleRepository(); 45 | } 46 | 47 | @Bean 48 | public PublishAuthCheck publishAuthCheck() { 49 | return new PublishAuthCheck(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/config/XBlogWebAppInitializer.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.config; 2 | 3 | import javax.servlet.Filter; 4 | 5 | import org.springframework.web.filter.HttpPutFormContentFilter; 6 | import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 7 | 8 | import com.huxuemin.xblog.web.WebConfig; 9 | 10 | public class XBlogWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{ 11 | 12 | @Override 13 | protected Class[] getRootConfigClasses() { 14 | // TODO Auto-generated method stub 15 | return new Class[]{RootConfig.class}; 16 | } 17 | 18 | @Override 19 | protected Class[] getServletConfigClasses() { 20 | // TODO Auto-generated method stub 21 | return new Class[]{WebConfig.class}; 22 | } 23 | 24 | @Override 25 | protected String[] getServletMappings() { 26 | // TODO Auto-generated method stub 27 | return new String[]{"/"}; 28 | } 29 | 30 | @Override 31 | protected Filter[] getServletFilters() { 32 | //Filter authFilter = new AuthFilter(); 33 | return new Filter[]{new HttpPutFormContentFilter()}; 34 | // return null; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/ConnectionAdapter.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Proxy; 6 | import java.sql.Connection; 7 | import java.sql.PreparedStatement; 8 | import java.sql.SQLException; 9 | 10 | import com.mysql.jdbc.exceptions.jdbc4.CommunicationsException; 11 | 12 | class ConnectionAdapter { 13 | private final long connectionIimeout = 8 * 60 * 60 * 1000 - 10 * 60 * 1000; 14 | private long lastIimeoutTest = 0L; 15 | private boolean isIdle = true; 16 | private long ownerThreadId = -1L; 17 | private Connection conn; 18 | private Connection proxyConn; 19 | 20 | public ConnectionAdapter(Connection conn,ConnectionPool pool){ 21 | this.conn = conn; 22 | this.proxyConn = (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), new Class[]{Connection.class}, new _Connection(conn,pool)); 23 | this.lastIimeoutTest = System.currentTimeMillis(); 24 | } 25 | 26 | public Connection getProxyConnection(){ 27 | if(markUsed()){ 28 | return proxyConn; 29 | }else{ 30 | return null; 31 | } 32 | } 33 | 34 | public void Close(){ 35 | try { 36 | if( conn != null && !conn.isClosed()){ 37 | conn.close(); 38 | } 39 | } catch (SQLException e) { 40 | // TODO Auto-generated catch block 41 | e.printStackTrace(); 42 | } 43 | } 44 | 45 | public boolean isInvalid(){ 46 | if(conn == null){return true;} 47 | if(proxyConn == null){return true;} 48 | if(connectionIsWaitTimeout()){return true;} 49 | 50 | try { 51 | if(!conn.isClosed()){ 52 | return false; 53 | } 54 | } catch (SQLException e1) { 55 | // TODO Auto-generated catch block 56 | e1.printStackTrace(); 57 | } 58 | return true; 59 | } 60 | 61 | private Boolean connectionIsWaitTimeout(){ 62 | boolean result = true; 63 | if((System.currentTimeMillis() - lastIimeoutTest) > connectionIimeout){ 64 | result = testConnectionIsOk(); 65 | }else{ 66 | result = false; 67 | } 68 | lastIimeoutTest = System.currentTimeMillis(); 69 | return result; 70 | } 71 | 72 | private boolean testConnectionIsOk(){ 73 | try{ 74 | PreparedStatement stat = conn.prepareStatement("select 1 from users where 1=2"); 75 | stat.execute(); 76 | stat.close(); 77 | return true; 78 | } catch (CommunicationsException e){ 79 | // TODO Auto-generated catch block 80 | e.printStackTrace(); 81 | } catch (SQLException e) { 82 | // TODO Auto-generated catch block 83 | e.printStackTrace(); 84 | } 85 | return false; 86 | } 87 | 88 | private boolean markUsed(){ 89 | if(!isIdle){ 90 | return false; 91 | } 92 | isIdle = false; 93 | ownerThreadId = Thread.currentThread().getId(); 94 | return true; 95 | } 96 | 97 | private boolean markIdle() throws Exception{ 98 | if(isIdle){return false;} 99 | 100 | if(ownerThreadId != Thread.currentThread().getId()){ 101 | throw new ConnectionException("Current ThreadId is " + Thread.currentThread().getId() + ",but the connection is used by " + ownerThreadId + " Thread!"); 102 | } 103 | 104 | isIdle = true; 105 | ownerThreadId = -1; 106 | return true; 107 | } 108 | 109 | private void checkStatus() throws Exception{ 110 | if(isIdle){ 111 | throw new ConnectionException("this connection is closed!"); 112 | } 113 | if(ownerThreadId != Thread.currentThread().getId()){ 114 | throw new ConnectionException("Current ThreadId is " + Thread.currentThread().getId() + ",but the connection is used by " + ownerThreadId + " Thread!"); 115 | } 116 | } 117 | 118 | private boolean isClosed(){ 119 | if(isIdle){return true;} 120 | if(ownerThreadId != Thread.currentThread().getId()){return true;} 121 | return false; 122 | } 123 | 124 | private class _Connection implements InvocationHandler{ 125 | private final Connection conn; 126 | private final ConnectionPool pool; 127 | 128 | _Connection(Connection conn,ConnectionPool pool){ 129 | this.conn = conn; 130 | this.pool = pool; 131 | } 132 | 133 | @Override 134 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 135 | // TODO Auto-generated method stub 136 | Object obj = null; 137 | if("close".equals(method.getName())){ 138 | if(markIdle()){ 139 | pool.push(ConnectionAdapter.this); 140 | } 141 | }else if("isClosed".equals(method.getName())){ 142 | obj = isClosed(); 143 | }else{ 144 | checkStatus(); 145 | obj = method.invoke(conn, args); 146 | } 147 | return obj; 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/ConnectionException.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database; 2 | 3 | import java.sql.SQLException; 4 | 5 | class ConnectionException extends SQLException { 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = 9146774388389821597L; 11 | 12 | public ConnectionException(String desc){ 13 | super(desc); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/ConnectionPool.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database; 2 | 3 | import java.sql.Connection; 4 | import java.util.ArrayList; 5 | import java.util.Iterator; 6 | 7 | class ConnectionPool { 8 | // private final static String TAG = "ConnectionPool"; 9 | private static ArrayList idleConnection = new ArrayList(); 10 | private static ArrayList usedConnection = new ArrayList(); 11 | 12 | public ConnectionPool(){} 13 | 14 | void push(ConnectionAdapter connAdapter){ 15 | // TODO Auto-generated method stub 16 | synchronized(ConnectionPool.class){ 17 | if(connAdapter != null){ 18 | usedConnection.remove(connAdapter); 19 | } 20 | 21 | if(connAdapter != null && !idleConnection.contains(connAdapter)){ 22 | idleConnection.add(connAdapter); 23 | } 24 | } 25 | // System.out.println(TAG + ",idle connection number: " + idleConnection.size()); 26 | // System.out.println(TAG + ",used connection number: " + usedConnection.size()); 27 | } 28 | 29 | public Connection pop(){ 30 | synchronized(ConnectionPool.class){ 31 | ConnectionAdapter connAdapter = null; 32 | if(idleConnection.isEmpty()){ 33 | connAdapter = createNewConnectionAdapter(); 34 | }else{ 35 | connAdapter = idleConnection.get(0); 36 | idleConnection.remove(connAdapter); 37 | if(connAdapter == null || connAdapter.isInvalid()){ 38 | connAdapter = createNewConnectionAdapter(); 39 | } 40 | } 41 | //System.out.println(TAG + ",pop()"); 42 | if(connAdapter != null && !usedConnection.contains(connAdapter)){ 43 | usedConnection.add(connAdapter); 44 | } 45 | return connAdapter.getProxyConnection(); 46 | } 47 | } 48 | 49 | private ConnectionAdapter createNewConnectionAdapter(){ 50 | return DBConnectionFactory.createNewConnectionAdapter(ConnectionPool.this); 51 | } 52 | 53 | public void releaseAllConnection() { 54 | // TODO Auto-generated method stub 55 | Iterator it = idleConnection.iterator(); 56 | while(it.hasNext()){ 57 | it.next().Close(); 58 | } 59 | 60 | it = usedConnection.iterator(); 61 | while(it.hasNext()){ 62 | it.next().Close(); 63 | } 64 | idleConnection.clear(); 65 | usedConnection.clear(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/DBConnectionFactory.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database; 2 | 3 | import java.sql.Connection; 4 | import java.util.Map; 5 | 6 | import com.huxuemin.xblog.database.mapper.BaseMapper; 7 | import com.huxuemin.xblog.database.mapper.MapperRegister; 8 | import com.huxuemin.xblog.database.mapper.TableAnnotationProcesser; 9 | import com.huxuemin.xblog.database.mapper.TableMap; 10 | import com.huxuemin.xblog.database.table.ArticleTable; 11 | import com.huxuemin.xblog.database.table.DiscussTable; 12 | import com.huxuemin.xblog.database.table.RoleAuthTable; 13 | import com.huxuemin.xblog.database.table.RolesTable; 14 | import com.huxuemin.xblog.database.table.UserRolesTable; 15 | import com.huxuemin.xblog.database.table.UserTable; 16 | 17 | public class DBConnectionFactory { 18 | 19 | private static MySqlDBManager connectionManager = new MySqlDBManager(); 20 | 21 | public static Connection getConnection() { 22 | return connectionManager.getConnection(); 23 | } 24 | 25 | public static void initDataBaseContext() { 26 | initTables(); 27 | initDomainMapper(); 28 | } 29 | 30 | private static void initDomainMapper() { 31 | Map, String> classToTablename = TableAnnotationProcesser 32 | .scanClassToTablenameMaps("com.huxuemin.xblog.domain"); 33 | for (Map.Entry, String> entry : classToTablename.entrySet()) { 34 | Class klass = entry.getKey(); 35 | String tableName = entry.getValue(); 36 | TableMap dm = new TableMap(tableName, klass).buildColumnAnnotation(); 37 | MapperRegister.register(klass, new BaseMapper(dm)); 38 | } 39 | } 40 | 41 | private static void initTables() { 42 | initTable(new UserTable()); 43 | initTable(new RoleAuthTable()); 44 | initTable(new RolesTable()); 45 | initTable(new ArticleTable()); 46 | initTable(new DiscussTable()); 47 | initTable(new UserRolesTable()); 48 | // initTable(new UserPublicInfoTable()); 49 | // initTable(new UserPrivateInfoTable()); 50 | } 51 | 52 | static ConnectionAdapter createNewConnectionAdapter(ConnectionPool pool) { 53 | return new ConnectionAdapter(connectionManager.createNewConnection(), pool); 54 | } 55 | 56 | private static void initTable(ITable tab) { 57 | connectionManager.initTable(tab); 58 | } 59 | 60 | public static void closeAllConnection() { 61 | connectionManager.closeAllConnection(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/ITable.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database; 2 | 3 | import java.sql.Connection; 4 | import java.sql.PreparedStatement; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | 8 | import com.mysql.jdbc.exceptions.jdbc4.CommunicationsException; 9 | 10 | public abstract class ITable { 11 | public boolean isExist(Connection conn){ 12 | boolean result = true; 13 | try{ 14 | PreparedStatement stat = conn.prepareStatement(getTestExistStatement()); 15 | stat.execute(); 16 | stat.close(); 17 | } catch (CommunicationsException e){ 18 | result = false; 19 | } catch (SQLException e) { 20 | // TODO Auto-generated catch block 21 | result = false; 22 | } finally{ 23 | try { 24 | conn.close(); 25 | } catch (SQLException e) { 26 | // TODO Auto-generated catch block 27 | e.printStackTrace(); 28 | } 29 | } 30 | return result; 31 | }; 32 | 33 | public void create(Connection conn){ 34 | Statement smt; 35 | try { 36 | smt = conn.createStatement(); 37 | String[] str = getCreateStatement(); 38 | for(int k = 0; k < str.length; k++){ 39 | smt.addBatch(str[k]); 40 | } 41 | smt.executeBatch(); 42 | smt.close(); 43 | if(!conn.getAutoCommit()){ 44 | conn.commit(); 45 | } 46 | } catch (SQLException e) { 47 | // TODO Auto-generated catch block 48 | e.printStackTrace(); 49 | } finally{ 50 | try { 51 | conn.close(); 52 | } catch (SQLException e) { 53 | // TODO Auto-generated catch block 54 | e.printStackTrace(); 55 | } 56 | } 57 | } 58 | protected abstract String getTestExistStatement(); 59 | protected abstract String[] getCreateStatement(); 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/MySqlDBManager.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | 8 | class MySqlDBManager{ 9 | private final static String TAG = "MysqlDBConnectionManager"; 10 | private final static String driverClassName = "com.mysql.jdbc.Driver"; 11 | private final String database = "blog"; 12 | private final String URL = "jdbc:mysql://localhost:3306/" + database + "?useSSL=false"; 13 | private final String USERNAME = "blog"; 14 | private final String PASSWORD = "blog"; 15 | private final String createDatabase = "create DATABASE "+ database +" CHARACTER SET utf8;"; 16 | private final String createUser = "create USER '" + USERNAME + "'@'localhost' IDENTIFIED BY '" + PASSWORD + "';"; 17 | private final String grantUser = "GRANT ALL PRIVILEGES ON " + database + ".* TO '" + USERNAME + "'@'localhost';"; 18 | private final String flush = "FLUSH PRIVILEGES;"; 19 | 20 | private final String ROOT_URL = "jdbc:mysql://localhost:3306/mysql?useSSL=false"; 21 | private final String ROOT_USERNAME = "root"; 22 | //private final String ROOT_PASSWORD = "7955909"; 23 | private final String ROOT_PASSWORD = "h7955909"; 24 | //private final String ROOT_PASSWORD = "Hh7955909+"; 25 | 26 | //private final static int intMaxConnectionNum = 50; 27 | //private int intConnectionNum = 0; 28 | 29 | private static ConnectionPool connPool = new ConnectionPool(); 30 | 31 | MySqlDBManager(){ 32 | try{ 33 | Class.forName(driverClassName); 34 | } catch(ClassNotFoundException ce){ 35 | ce.printStackTrace(); 36 | } 37 | initDatabase(); 38 | } 39 | 40 | public Connection getConnection() { 41 | // TODO Auto-generated method stub 42 | return connPool.pop(); 43 | } 44 | 45 | public void closeAllConnection() { 46 | connPool.releaseAllConnection(); 47 | } 48 | 49 | private void initDatabase(){ 50 | if(!DatabaseIsExist()){ 51 | switchRootInitDatabase(); 52 | } 53 | } 54 | 55 | private boolean DatabaseIsExist(){ 56 | boolean result = false; 57 | Connection conn = null; 58 | try { 59 | conn = (Connection) DriverManager.getConnection(URL, USERNAME, PASSWORD); 60 | result = true; 61 | } catch (SQLException e) { 62 | // TODO Auto-generated catch block 63 | //e.printStackTrace(); 64 | } finally{ 65 | try { 66 | if(conn != null){ 67 | conn.close(); 68 | } 69 | } catch (SQLException e) { 70 | // TODO Auto-generated catch block 71 | e.printStackTrace(); 72 | } 73 | } 74 | return result; 75 | } 76 | 77 | private void switchRootInitDatabase(){ 78 | try { 79 | Connection conn = DriverManager.getConnection(ROOT_URL, ROOT_USERNAME, ROOT_PASSWORD); 80 | Statement smt = conn.createStatement(); 81 | smt.addBatch(createDatabase); 82 | smt.addBatch(createUser); 83 | smt.addBatch(grantUser); 84 | smt.addBatch(flush); 85 | smt.executeBatch(); 86 | smt.close(); 87 | if(!conn.getAutoCommit()){ 88 | conn.commit(); 89 | } 90 | conn.close(); 91 | } catch (SQLException e) { 92 | // TODO Auto-generated catch block 93 | e.printStackTrace(); 94 | } 95 | } 96 | 97 | public void initTable(ITable tab){ 98 | if(!tab.isExist(getConnection())){ 99 | tab.create(getConnection()); 100 | } 101 | } 102 | 103 | public boolean tableIsExist(ITable tab){ 104 | return tab.isExist(getConnection()); 105 | } 106 | 107 | Connection createNewConnection(){ 108 | Connection conn = null; 109 | try { 110 | conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); 111 | } catch (SQLException e) { 112 | // TODO Auto-generated catch block 113 | e.printStackTrace(); 114 | } 115 | System.out.println(TAG + ",createNewConnection()!"); 116 | return conn; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/ColumnAnnotationProcesser.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | public class ColumnAnnotationProcesser { 6 | 7 | public static void columnToFieldMaps(TableMap dataMap) { 8 | Field[] fields = dataMap.getKlass().getDeclaredFields(); 9 | if (fields != null) { 10 | for (int i = 0; i < fields.length; i++) { 11 | Field field = fields[i]; 12 | PrimaryKeyColumn(dataMap,field); 13 | OneToOneColumn(dataMap,field); 14 | OneToManyColumn(dataMap,field); 15 | OneToOneDomainObject(dataMap,field); 16 | OneToManyDomainObject(dataMap,field); 17 | } 18 | } 19 | } 20 | 21 | private static void PrimaryKeyColumn(TableMap dataMap, Field field) { 22 | if (field.isAnnotationPresent(PrimaryKeyColumn.class)) { 23 | PrimaryKeyColumn columnAnnotation = field.getAnnotation(PrimaryKeyColumn.class); 24 | String columnName = columnAnnotation.columnName(); 25 | dataMap.setPrimaryKeyColumn(columnName, field.getName()); 26 | } 27 | } 28 | 29 | private static void OneToOneColumn(TableMap dataMap, Field field) { 30 | if (field.isAnnotationPresent(OneToOneColumn.class)) { 31 | OneToOneColumn columnAnnotation = field.getAnnotation(OneToOneColumn.class); 32 | String columnName = columnAnnotation.columnName(); 33 | dataMap.addOneToOneColumn(columnName, field.getName()); 34 | } 35 | } 36 | 37 | private static void OneToManyColumn(TableMap dataMap, Field field) { 38 | if (field.isAnnotationPresent(OneToManyColumn.class)) { 39 | OneToManyColumn columnAnnotation = field.getAnnotation(OneToManyColumn.class); 40 | String columnName = columnAnnotation.columnName(); 41 | String foreignKeyColumnName = columnAnnotation.foreignKeyColumnName(); 42 | String foreigntableName = columnAnnotation.foreigntableName(); 43 | dataMap.addOneToManyColumn(columnName, foreignKeyColumnName, foreigntableName, field.getName()); 44 | } 45 | } 46 | 47 | private static void OneToOneDomainObject(TableMap dataMap, Field field) { 48 | if (field.isAnnotationPresent(OneToOneDomainObject.class)) { 49 | OneToOneDomainObject columnAnnotation = field.getAnnotation(OneToOneDomainObject.class); 50 | String foreignKeyColumnName = columnAnnotation.foreignKeyColumnName(); 51 | Class cls = columnAnnotation.foreignKeyDomainClass(); 52 | dataMap.addOneToOneDomainObject(foreignKeyColumnName, cls, field.getName()); 53 | } 54 | } 55 | 56 | private static void OneToManyDomainObject(TableMap dataMap, Field field) { 57 | if (field.isAnnotationPresent(OneToManyDomainObject.class)) { 58 | OneToManyDomainObject columnAnnotation = field.getAnnotation(OneToManyDomainObject.class); 59 | String foreignKeyColumnName = columnAnnotation.foreignKeyColumnName(); 60 | Class cls = columnAnnotation.foreignKeyDomainClass(); 61 | dataMap.addOneToManyDomainObject(foreignKeyColumnName, cls, field.getName()); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/ColumnOneToManyMap.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | public class ColumnOneToManyMap { 4 | private ColumnOneToOneMap columnMap; 5 | private String foreignKeyColumnName; 6 | private String foreigntableName; 7 | 8 | public ColumnOneToManyMap(ColumnOneToOneMap columnMap, String foreignKeyColumnName, String foreigntableName){ 9 | this.columnMap = columnMap; 10 | this.foreignKeyColumnName = foreignKeyColumnName; 11 | this.foreigntableName = foreigntableName; 12 | } 13 | 14 | public String selectSQL(){ 15 | return "SELECT " + columnList() + " FROM " + foreigntableName + " WHERE " + foreignKeyColumnName + " = ? "; 16 | } 17 | 18 | public String insertSQL(){ 19 | return "INSERT INTO " + foreigntableName + "(" + columnList() + ") VALUES(?,?)"; 20 | } 21 | 22 | public String deleteSQL(){ 23 | return "DELETE FROM " + foreigntableName + " WHERE " + foreignKeyColumnName + " = ? "; 24 | } 25 | 26 | private String columnList(){ 27 | return " " + foreignKeyColumnName + "," + columnMap.getColumnName() + " "; 28 | } 29 | 30 | public String getColumnName(){ 31 | return this.columnMap.getColumnName(); 32 | } 33 | 34 | public String getFieldName(){ 35 | return this.columnMap.getFieldName(); 36 | } 37 | 38 | public Object getValue(Object subject){ 39 | return columnMap.getValue(subject); 40 | } 41 | 42 | public void setField(Object result,Object columnValue){ 43 | columnMap.setField(result, columnValue); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/ColumnOneToOneMap.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | public class ColumnOneToOneMap { 6 | private String columnName; 7 | private String fieldName; 8 | protected Field field; 9 | private TableMap dataMap; 10 | 11 | public ColumnOneToOneMap(String columnName,String fieldName,TableMap dataMap){ 12 | this.columnName = columnName; 13 | this.fieldName = fieldName; 14 | this.dataMap = dataMap; 15 | initField(); 16 | } 17 | 18 | public String getColumnName(){ 19 | return this.columnName; 20 | } 21 | 22 | public String getFieldName(){ 23 | return this.fieldName; 24 | } 25 | 26 | public Object getValue(Object subject){ 27 | try { 28 | return field.get(subject); 29 | } catch (IllegalArgumentException e) { 30 | // TODO Auto-generated catch block 31 | e.printStackTrace(); 32 | } catch (IllegalAccessException e) { 33 | // TODO Auto-generated catch block 34 | e.printStackTrace(); 35 | } 36 | return null; 37 | } 38 | 39 | public void setField(Object result,Object columnValue){ 40 | try { 41 | field.set(result, columnValue); 42 | } catch (IllegalArgumentException e) { 43 | // TODO Auto-generated catch block 44 | e.printStackTrace(); 45 | } catch (IllegalAccessException e) { 46 | // TODO Auto-generated catch block 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | protected void initField(){ 52 | try { 53 | this.field = dataMap.getKlass().getDeclaredField(getFieldName()); 54 | field.setAccessible(true); 55 | } catch (NoSuchFieldException e) { 56 | // TODO Auto-generated catch block 57 | e.printStackTrace(); 58 | } catch (SecurityException e) { 59 | // TODO Auto-generated catch block 60 | e.printStackTrace(); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/Criteria.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import com.huxuemin.xblog.infrastructure.DomainObject; 4 | 5 | public class Criteria { 6 | private String sqlOperator; 7 | private String fieldName; 8 | private Object value; 9 | 10 | public static Criteria equalTo(String fieldName,String value){ 11 | return new Criteria(" = ",fieldName,value); 12 | } 13 | 14 | private Criteria(String sql,String fieldName,Object value){ 15 | this.sqlOperator = sql; 16 | this.fieldName = fieldName; 17 | this.value = value; 18 | } 19 | 20 | public String generateSql(TableMap dataMap){ 21 | return dataMap.getColumnForField(fieldName) + sqlOperator + value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/CriteriaOperator.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | public enum CriteriaOperator { 4 | NONE, 5 | EQ,//= 6 | GT,//> 7 | LT //< 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/DomainObjectMap.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import com.huxuemin.xblog.infrastructure.DomainObject; 6 | 7 | public class DomainObjectMap { 8 | private String fieldName; 9 | protected Field field; 10 | private TableMap dataMap; 11 | private String foreignKeyColumnName; 12 | private Class domainClass; 13 | 14 | public DomainObjectMap(String foreignKeyColumnName,Class domainClass,TableMap dataMap,String fieldName){ 15 | this.fieldName = fieldName; 16 | this.foreignKeyColumnName = foreignKeyColumnName; 17 | this.domainClass = domainClass; 18 | this.dataMap = dataMap; 19 | initField(); 20 | } 21 | 22 | public Class getDomainClass(){ 23 | return domainClass; 24 | } 25 | 26 | public String getWhereClause(){ 27 | return foreignKeyColumnName + " = ? "; 28 | } 29 | 30 | public String getWhereClause(String foreignKeyColumnValue){ 31 | return foreignKeyColumnName + " = " + "'" + foreignKeyColumnValue + "'"; 32 | } 33 | 34 | public String getFieldName(){ 35 | return this.fieldName; 36 | } 37 | 38 | public Object getValue(Object subject){ 39 | try { 40 | return field.get(subject); 41 | } catch (IllegalArgumentException e) { 42 | // TODO Auto-generated catch block 43 | e.printStackTrace(); 44 | } catch (IllegalAccessException e) { 45 | // TODO Auto-generated catch block 46 | e.printStackTrace(); 47 | } 48 | return null; 49 | } 50 | 51 | public void setField(Object result,Object columnValue){ 52 | try { 53 | field.set(result, columnValue); 54 | } catch (IllegalArgumentException e) { 55 | // TODO Auto-generated catch block 56 | e.printStackTrace(); 57 | } catch (IllegalAccessException e) { 58 | // TODO Auto-generated catch block 59 | e.printStackTrace(); 60 | } 61 | } 62 | 63 | protected void initField(){ 64 | try { 65 | this.field = dataMap.getKlass().getDeclaredField(getFieldName()); 66 | field.setAccessible(true); 67 | } catch (NoSuchFieldException e) { 68 | // TODO Auto-generated catch block 69 | e.printStackTrace(); 70 | } catch (SecurityException e) { 71 | // TODO Auto-generated catch block 72 | e.printStackTrace(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/MapperRegister.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class MapperRegister { 7 | public static Map map = new HashMap(); 8 | 9 | public static void register(Class cls,BaseMapper mapper){ 10 | map.put(cls, mapper); 11 | } 12 | 13 | public static void unRegister(Class cls){ 14 | map.remove(cls); 15 | } 16 | 17 | public static BaseMapper getMapper(Class cls){ 18 | return map.get(cls); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/OneToManyColumn.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.FIELD) 10 | public @interface OneToManyColumn { 11 | public String columnName() ; 12 | public String foreignKeyColumnName(); 13 | public String foreigntableName(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/OneToManyDomainObject.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.FIELD) 10 | public @interface OneToManyDomainObject { 11 | public String foreignKeyColumnName(); 12 | public Class foreignKeyDomainClass(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/OneToOneColumn.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.FIELD) 10 | public @interface OneToOneColumn { 11 | public String columnName(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/OneToOneDomainObject.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.FIELD) 10 | public @interface OneToOneDomainObject { 11 | public String foreignKeyColumnName(); 12 | public Class foreignKeyDomainClass(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/PrimaryKeyColumn.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.FIELD) 10 | public @interface PrimaryKeyColumn { 11 | public String columnName(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/QueryObject.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | public class QueryObject { 8 | private Class klass; 9 | private List criterias = new ArrayList(); 10 | 11 | public QueryObject(Class klass){ 12 | this.klass = klass; 13 | } 14 | 15 | public void addCriteria(Criteria criteria){ 16 | if(!criterias.contains(criteria)){ 17 | criterias.add(criteria); 18 | } 19 | } 20 | 21 | public String generateWhereClause(){ 22 | StringBuffer result = new StringBuffer(); 23 | for(Iterator it = criterias.iterator();it.hasNext();){ 24 | Criteria c = it.next(); 25 | if(result.length() != 0){ 26 | result.append(" AND "); 27 | } 28 | result .append(c.generateSql(MapperRegister.getMapper(klass).getTableMap())); 29 | } 30 | return result.toString(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/SqlTransactionException.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | public class SqlTransactionException extends RuntimeException{ 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = -5278972270682020275L; 9 | 10 | public SqlTransactionException(String message){ 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/Table.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | public @interface Table { 11 | public String name(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/TableAnnotationProcesser.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import com.huxuemin.xblog.infrastructure.tools.ClasspathPackageScanner; 10 | 11 | public class TableAnnotationProcesser { 12 | 13 | private final static Class tableClass = Table.class; 14 | 15 | private static String getTableName(Class bean){ 16 | Table table = bean.getAnnotation(tableClass); 17 | return table.name(); 18 | } 19 | 20 | public static Map,String> scanClassToTablenameMaps(String packageName){ 21 | ClasspathPackageScanner cps = new ClasspathPackageScanner(packageName); 22 | Map,String> classAndTablename = new HashMap,String>(); 23 | try { 24 | List allPackageClassName = cps.getFullyQualifiedClassNameList(); 25 | for(Iterator it = allPackageClassName.iterator();it.hasNext();){ 26 | String className = it.next(); 27 | Class klass = Class.forName(className); 28 | if(klass.isAnnotationPresent(tableClass)){ 29 | classAndTablename.put(klass, getTableName(klass)); 30 | } 31 | } 32 | } catch (IOException e) { 33 | // TODO Auto-generated catch block 34 | e.printStackTrace(); 35 | } catch (ClassNotFoundException e) { 36 | // TODO Auto-generated catch block 37 | e.printStackTrace(); 38 | } 39 | return classAndTablename; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/mapper/TableMap.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.mapper; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | import com.huxuemin.xblog.infrastructure.DomainObject; 8 | 9 | public class TableMap { 10 | private Class domainClass; 11 | private String tableName; 12 | private ColumnOneToOneMap primaryKeyColumn; 13 | private List oneToOneColumnMaps = new ArrayList(); 14 | private List oneToManyColumnMaps = new ArrayList(); 15 | private List oneToOneDomainObjectMaps = new ArrayList(); 16 | private List oneToManyDomainObjectMaps = new ArrayList(); 17 | 18 | public TableMap(String tableName,Class domainClass){ 19 | this.domainClass = domainClass; 20 | this.tableName = tableName; 21 | } 22 | 23 | public void addOneToOneColumn(String columnName,String fieldName){ 24 | ColumnOneToOneMap columnMap = new ColumnOneToOneMap(columnName,fieldName,this); 25 | if(!oneToOneColumnMaps.contains(columnMap)){ 26 | if(primaryKeyColumn == null){ 27 | primaryKeyColumn = columnMap; 28 | } 29 | oneToOneColumnMaps.add(columnMap); 30 | } 31 | } 32 | 33 | public void addOneToManyColumn(String columnName,String foreignKeyColumnName,String foreigntableName,String fieldName){ 34 | ColumnOneToOneMap columnMap = new ColumnOneToOneMap(columnName,fieldName,this); 35 | ColumnOneToManyMap oneToManyColumnMap = new ColumnOneToManyMap(columnMap,foreignKeyColumnName,foreigntableName); 36 | if(!oneToManyColumnMaps.contains(oneToManyColumnMap)){ 37 | oneToManyColumnMaps.add(oneToManyColumnMap); 38 | } 39 | } 40 | 41 | public void addOneToOneDomainObject(String foreignKeyColumnName,Class foreignKeyDomainClass,String fieldName){ 42 | DomainObjectMap oneToOneDomainObjectMap = new DomainObjectMap(foreignKeyColumnName,foreignKeyDomainClass,this,fieldName); 43 | if(!oneToOneDomainObjectMaps.contains(oneToOneDomainObjectMap)){ 44 | oneToOneDomainObjectMaps.add(oneToOneDomainObjectMap); 45 | } 46 | } 47 | 48 | public void addOneToManyDomainObject(String foreignKeyColumnName,Class foreignKeyDomainClass,String fieldName){ 49 | DomainObjectMap oneToManyDomainObjectMap = new DomainObjectMap(foreignKeyColumnName,foreignKeyDomainClass,this,fieldName); 50 | if(!oneToManyDomainObjectMaps.contains(oneToManyDomainObjectMap)){ 51 | oneToManyDomainObjectMaps.add(oneToManyDomainObjectMap); 52 | } 53 | } 54 | 55 | public Class getKlass(){ 56 | return this.domainClass; 57 | } 58 | 59 | public void setPrimaryKeyColumn(String columnName, String fieldName){ 60 | this.primaryKeyColumn = new ColumnOneToOneMap(columnName,fieldName,this); 61 | if(!oneToOneColumnMaps.contains(primaryKeyColumn)){ 62 | oneToOneColumnMaps.add(primaryKeyColumn); 63 | } 64 | } 65 | 66 | public String primaryKeyWhereClause(){ 67 | return primaryKeyColumn.getColumnName() + " = ? "; 68 | } 69 | 70 | public Object primaryKeyColumnName(){ 71 | return primaryKeyColumn.getColumnName(); 72 | } 73 | 74 | public Object primaryKeyValue(Object domainObject){ 75 | return primaryKeyColumn.getValue(domainObject); 76 | } 77 | 78 | public String getTableName(){ 79 | return this.tableName; 80 | } 81 | 82 | public String insertList(){ 83 | StringBuffer result = new StringBuffer("?"); 84 | for(int i = 0;i < oneToOneColumnMaps.size() - 1;i++){ 85 | result.append(","); 86 | result.append("?"); 87 | } 88 | return result.toString(); 89 | } 90 | 91 | public String columnList(){ 92 | StringBuffer result = new StringBuffer(" "); 93 | for(Iterator it = getOneToOneColumns();it.hasNext();){ 94 | ColumnOneToOneMap columnMap = it.next(); 95 | result.append(columnMap.getColumnName()); 96 | result.append(","); 97 | } 98 | result.setLength(result.length() - 1); 99 | return result.toString(); 100 | } 101 | 102 | public String updateList(){ 103 | StringBuffer result = new StringBuffer(" SET "); 104 | for(Iterator it = getOneToOneColumns();it.hasNext();){ 105 | ColumnOneToOneMap column = it.next(); 106 | result.append(column.getColumnName()); 107 | result.append("=?,"); 108 | } 109 | result.setLength(result.length() - 1); 110 | return result.toString(); 111 | } 112 | 113 | public String getColumnForField(String fieldName){ 114 | for(Iterator it = getOneToOneColumns();it.hasNext();){ 115 | ColumnOneToOneMap columnMap = it.next(); 116 | if(columnMap.getFieldName().equals(fieldName)){ 117 | return columnMap.getColumnName(); 118 | } 119 | } 120 | return null; 121 | } 122 | 123 | public Iterator getOneToOneColumns(){ 124 | return oneToOneColumnMaps.iterator(); 125 | } 126 | 127 | public Iterator getOneToManyColumns(){ 128 | return oneToManyColumnMaps.iterator(); 129 | } 130 | 131 | public Iterator getOnetoOneDomainObjects(){ 132 | return oneToOneDomainObjectMaps.iterator(); 133 | } 134 | 135 | public Iterator getOneToManyDomainObjects(){ 136 | return oneToManyDomainObjectMaps.iterator(); 137 | } 138 | 139 | public TableMap buildColumnAnnotation(){ 140 | ColumnAnnotationProcesser.columnToFieldMaps(this); 141 | return this; 142 | } 143 | 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/table/ArticleTable.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.table; 2 | 3 | import com.huxuemin.xblog.database.ITable; 4 | 5 | public class ArticleTable extends ITable { 6 | private String dropTabel = "DROP TABLE IF EXISTS `articles`;"; 7 | private String createTabel = "CREATE TABLE `articles` (" 8 | + "`id` bigint(63) NOT NULL," 9 | + "`title` varchar(255) DEFAULT NULL," 10 | + "`content` text DEFAULT NULL," 11 | + "`toptime` datetime DEFAULT NULL," 12 | + "`updatetime` datetime DEFAULT NULL," 13 | + "`category` varchar(255) DEFAULT NULL," 14 | + "`owerusername` varchar(255) DEFAULT NULL," 15 | + "`candiscussstatus` tinyint(1) NOT NULL DEFAULT '0'," 16 | + "`articlestatus` int(4) DEFAULT NULL," 17 | + "`lastreplytime` datetime DEFAULT NULL," 18 | + " PRIMARY KEY (`id`)," 19 | + " KEY `index_articles_title` (`title`)" 20 | + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; 21 | 22 | @Override 23 | protected String[] getCreateStatement() { 24 | // TODO Auto-generated method stub 25 | return new String[] { dropTabel, createTabel}; 26 | } 27 | 28 | @Override 29 | protected String getTestExistStatement() { 30 | // TODO Auto-generated method stub 31 | return "select 1 from articles where 1=2"; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/table/DiscussTable.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.table; 2 | 3 | import com.huxuemin.xblog.database.ITable; 4 | 5 | public class DiscussTable extends ITable{ 6 | 7 | private String dropTabel = "DROP TABLE IF EXISTS `discusses`;"; 8 | private String createTabel = "CREATE TABLE `discusses` (" + 9 | "`id` bigint(63) NOT NULL," + 10 | "`content` text DEFAULT NULL," + 11 | "`articleid` bigint (63) NOT NULL," + 12 | "`replyid` bigint (63) NOT NULL," + 13 | "`username` varchar(255) DEFAULT NULL," + 14 | "`createon` datetime DEFAULT NULL," + 15 | " PRIMARY KEY (`id`)," + 16 | " KEY `index_discusses_articleid` (`articleid`)" + 17 | ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; 18 | 19 | @Override 20 | protected String[] getCreateStatement() { 21 | // TODO Auto-generated method stub 22 | return new String[] { dropTabel, createTabel}; 23 | } 24 | 25 | @Override 26 | protected String getTestExistStatement() { 27 | // TODO Auto-generated method stub 28 | return "select 1 from discusses where 1=2"; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/table/RoleAuthTable.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.table; 2 | 3 | import com.huxuemin.xblog.database.ITable; 4 | import com.huxuemin.xblog.infrastructure.AuthConstant; 5 | 6 | public class RoleAuthTable extends ITable { 7 | 8 | private String dropTabel = "DROP TABLE IF EXISTS `rolesauth`;"; 9 | 10 | private String createTabel = "CREATE TABLE `rolesauth` (" 11 | + "`name` varchar(255) NOT NULL DEFAULT ''," 12 | + "`authority` varchar(255) NOT NULL DEFAULT ''," 13 | + "PRIMARY KEY (`name`,`authority`)" 14 | + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; 15 | 16 | private String initAdmin1 = "INSERT INTO rolesauth(name,authority) VALUES('admin','" + AuthConstant.ROLE_MANAGER + "')"; 17 | private String initAdmin2 = "INSERT INTO rolesauth(name,authority) VALUES('admin','" + AuthConstant.ARTICLE_MANAGER + "')"; 18 | private String initAdmin3 = "INSERT INTO rolesauth(name,authority) VALUES('admin','" + AuthConstant.DISCUSS_MANAGER + "')"; 19 | private String initAdmin4 = "INSERT INTO rolesauth(name,authority) VALUES('admin','" + AuthConstant.USER_MANAGER + "')"; 20 | private String initAdmin5 = "INSERT INTO rolesauth(name,authority) VALUES('admin','" + AuthConstant.PUBLIC_DISCUSS + "')"; 21 | private String initAdmin6 = "INSERT INTO rolesauth(name,authority) VALUES('admin','" + AuthConstant.MANAGE_PAGE + "')"; 22 | 23 | private String initManager1 = "INSERT INTO rolesauth(name,authority) VALUES('manager','" + AuthConstant.USER_MANAGER + "')"; 24 | private String initManager2 = "INSERT INTO rolesauth(name,authority) VALUES('manager','" + AuthConstant.DISCUSS_MANAGER + "')"; 25 | private String initManager3 = "INSERT INTO rolesauth(name,authority) VALUES('manager','" + AuthConstant.PUBLIC_DISCUSS + "')"; 26 | private String initManager4 = "INSERT INTO rolesauth(name,authority) VALUES('manager','" + AuthConstant.MANAGE_PAGE + "')"; 27 | 28 | private String initUser1 = "INSERT INTO rolesauth(name,authority) VALUES('user','" + AuthConstant.PUBLIC_DISCUSS + "')"; 29 | 30 | @Override 31 | protected String[] getCreateStatement() { 32 | // TODO Auto-generated method stub 33 | return new String[] { dropTabel, createTabel, 34 | initAdmin1, initAdmin2, initAdmin3, initAdmin4,initAdmin5,initAdmin6, 35 | initManager1, initManager2,initManager3,initManager4, 36 | initUser1 37 | }; 38 | } 39 | 40 | @Override 41 | protected String getTestExistStatement() { 42 | // TODO Auto-generated method stub 43 | return "select 1 from rolesauth where 1=2"; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/table/RolesTable.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.table; 2 | 3 | import com.huxuemin.xblog.database.ITable; 4 | 5 | public class RolesTable extends ITable { 6 | 7 | private String dropTabel = "DROP TABLE IF EXISTS `roles`;"; 8 | 9 | private String createTabel = "CREATE TABLE `roles` (" 10 | + "`name` varchar(255) NOT NULL DEFAULT ''," 11 | + "PRIMARY KEY (`name`)" 12 | + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; 13 | 14 | private String initAdmin1 = "INSERT INTO ROLES(name) VALUES('admin')"; 15 | 16 | private String initManager1 = "INSERT INTO ROLES(name) VALUES('manager')"; 17 | 18 | private String initUser1 = "INSERT INTO ROLES(name) VALUES('user')"; 19 | 20 | @Override 21 | protected String[] getCreateStatement() { 22 | // TODO Auto-generated method stub 23 | return new String[] { dropTabel, createTabel, 24 | initAdmin1, 25 | initManager1, 26 | initUser1 27 | }; 28 | } 29 | 30 | @Override 31 | protected String getTestExistStatement() { 32 | // TODO Auto-generated method stub 33 | return "select 1 from roles where 1=2"; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/table/UserPrivateInfoTable.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.table; 2 | 3 | import com.huxuemin.xblog.database.ITable; 4 | 5 | class UserPrivateInfoTable extends ITable{ 6 | private String dropTabel = "DROP TABLE IF EXISTS `userprivateinfo`;"; 7 | private String createTabel = "CREATE TABLE `userprivateinfo` (" 8 | + "`username` varchar(255) NOT NULL DEFAULT ''," 9 | + "`phoneNum` varchar(255) DEFAULT NULL," 10 | + "`address` varchar(255) DEFAULT NULL," 11 | + "`qq` varchar(255) DEFAULT NULL," 12 | + "`wechat` varchar(255) DEFAULT NULL," 13 | + "`email` varchar(255) DEFAULT NULL," 14 | + " PRIMARY KEY (`username`)" 15 | + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; 16 | 17 | private String initAdmin1 = "INSERT INTO userprivateinfo(username,phoneNum,address,qq,wechat,email)" 18 | + " VALUES('admin','13066961905','','397997401','hu-xuemin','dev13@huxuemin.com');"; 19 | 20 | @Override 21 | protected String[] getCreateStatement() { 22 | // TODO Auto-generated method stub 23 | return new String[] { dropTabel, createTabel,initAdmin1}; 24 | } 25 | 26 | @Override 27 | protected String getTestExistStatement() { 28 | // TODO Auto-generated method stub 29 | return "select 1 from userprivateinfo where 1=2 "; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/table/UserPublicInfoTable.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.table; 2 | 3 | import com.huxuemin.xblog.database.ITable; 4 | 5 | class UserPublicInfoTable extends ITable{ 6 | private String dropTabel = "DROP TABLE IF EXISTS `userpublicinfo`;"; 7 | private String createTabel = "CREATE TABLE `userpublicinfo` (" 8 | + "`username` varchar(255) NOT NULL DEFAULT ''," 9 | + "`firstname` varchar(255) DEFAULT NULL," 10 | + "`lastname` varchar(255) DEFAULT NULL," 11 | + "`lang` varchar(255) DEFAULT NULL," 12 | + "`profession` varchar(255) DEFAULT NULL," 13 | + "`country` varchar(255) DEFAULT NULL," 14 | + "`sex` varchar(255) DEFAULT NULL," 15 | + "`birthday` datetime DEFAULT NULL," 16 | + "`profile` varchar(255) DEFAULT NULL," 17 | + " PRIMARY KEY (`username`)" 18 | + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; 19 | 20 | private String initAdmin1 = "INSERT INTO userpublicinfo(username,firstname,lastname,lang,profession,country,sex,birthday,profile)" 21 | + " VALUES('admin','','admin','','IT','','man','1987-01-01','�����ͻ�ϸ��Ǿޱ');"; 22 | 23 | @Override 24 | protected String[] getCreateStatement() { 25 | // TODO Auto-generated method stub 26 | return new String[] { dropTabel, createTabel,initAdmin1}; 27 | } 28 | 29 | @Override 30 | protected String getTestExistStatement() { 31 | // TODO Auto-generated method stub 32 | return "select 1 from userpublicinfo where 1=2 "; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/table/UserRolesTable.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.database.table; 2 | 3 | import com.huxuemin.xblog.database.ITable; 4 | 5 | public class UserRolesTable extends ITable{ 6 | 7 | private String deleteUser = "DROP TABLE IF EXISTS `userrole`;"; 8 | private String createUser = "CREATE TABLE `userrole` (" 9 | + "`username` varchar(255) NOT NULL DEFAULT ''," 10 | + "`rolename` varchar(255) NOT NULL DEFAULT ''," 11 | + "PRIMARY KEY (`username`,`rolename`)" 12 | + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; 13 | 14 | private String initAdmin1 = "INSERT INTO userrole(username,rolename)" 15 | + " VALUES('admin','admin');"; 16 | 17 | @Override 18 | protected String[] getCreateStatement() { 19 | // TODO Auto-generated method stub 20 | return new String[]{ 21 | deleteUser, 22 | createUser, 23 | initAdmin1 24 | }; 25 | } 26 | 27 | @Override 28 | protected String getTestExistStatement() { 29 | // TODO Auto-generated method stub 30 | return "select 1 from userrole where 1=2"; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/database/table/UserTable.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/java/com/huxuemin/xblog/database/table/UserTable.java -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/article/ArticleFactory.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.article; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | 8 | import com.huxuemin.xblog.domain.repository.RepositoryRegister; 9 | import com.huxuemin.xblog.domain.user.User; 10 | import com.huxuemin.xblog.infrastructure.dtos.ArticleDTO; 11 | import com.huxuemin.xblog.infrastructure.dtos.ArticleSummaryDTO; 12 | import com.huxuemin.xblog.infrastructure.dtos.DiscussDTO; 13 | import com.huxuemin.xblog.infrastructure.tools.HTMLEscape; 14 | import com.huxuemin.xblog.infrastructure.tools.IDCreateFactory; 15 | 16 | public class ArticleFactory { 17 | 18 | public static long getId() { 19 | return IDCreateFactory.getId(); 20 | } 21 | 22 | public static ArticleDTO createArticleDTO(Article article) { 23 | if (article != null) { 24 | ArticleDTO dto = new ArticleDTO(); 25 | dto.setArtileId(article.getArticleId()); 26 | dto.setArticleTitle((article.getTitle())); 27 | dto.setArticleContent(article.getArticleContent()); 28 | return dto; 29 | } else { 30 | return null; 31 | } 32 | } 33 | 34 | public static List createArticleSummaryDTOs(List
articles) { 35 | Iterator
it = articles.iterator(); 36 | List articleSummarys = new ArrayList(); 37 | Article article; 38 | ArticleSummaryDTO as; 39 | while (it.hasNext()) { 40 | article = it.next(); 41 | as = new ArticleSummaryDTO(); 42 | as.setId(article.getArticleId()); 43 | as.setTitle(article.getTitle()); 44 | articleSummarys.add(as); 45 | } 46 | return articleSummarys; 47 | } 48 | 49 | public static List createDiscussDTOs(Article articles, int begin, int end) 50 | throws DiscussNotFoundException { 51 | List dtoList = new ArrayList(); 52 | if (articles != null) { 53 | List discussList = null; 54 | discussList = articles.getDiscusses(begin, end); 55 | Iterator it = discussList.iterator(); 56 | while (it.hasNext()) { 57 | dtoList.add(createDiscussDTO(articles, it.next())); 58 | } 59 | } 60 | return dtoList; 61 | } 62 | 63 | public static DiscussDTO createDiscussDTO(Article articles, Discuss discuss) { 64 | DiscussDTO dto = new DiscussDTO(discuss.getDiscussId()); 65 | dto.setContent(HTMLEscape.escape(discuss.getDiscussContent())); 66 | dto.setCreateOn(discuss.getCreateOn()); 67 | dto.setOwerUserName(discuss.getUserName()); 68 | dto.setOwerDisplayName(userNameTodisplayName(discuss.getUserName())); 69 | Discuss reply = articles.getDiscuss(discuss.getReplyId()); 70 | if (reply != null) { 71 | dto.setReplyUserName(reply.getUserName()); 72 | dto.setReplyDisName(userNameTodisplayName(reply.getUserName())); 73 | } 74 | return dto; 75 | } 76 | 77 | private static String userNameTodisplayName(String userName) { 78 | User user = RepositoryRegister.getUserRepository().get(userName); 79 | if (user != null) { 80 | return user.getUserDisplayName(); 81 | } else { 82 | return ""; 83 | } 84 | } 85 | 86 | public static Article createArticle(String username, String title, String articlecontent) { 87 | Article article = new Article(getId(), username, title, articlecontent); 88 | article.openDiscuss(); 89 | article.classify("talk"); 90 | article.top(new Date(System.currentTimeMillis())); 91 | return article; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/article/ArticleNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.article; 2 | 3 | public class ArticleNotFoundException extends RuntimeException{ 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 8446139906935067570L; 9 | 10 | public ArticleNotFoundException(){ 11 | super("Article not found!"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/article/Discuss.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.article; 2 | 3 | import java.util.Date; 4 | 5 | import com.huxuemin.xblog.database.mapper.OneToOneColumn; 6 | import com.huxuemin.xblog.database.mapper.PrimaryKeyColumn; 7 | import com.huxuemin.xblog.database.mapper.Table; 8 | import com.huxuemin.xblog.infrastructure.DomainObject; 9 | 10 | @Table(name="DISCUSSES") 11 | public class Discuss extends DomainObject { 12 | 13 | @PrimaryKeyColumn(columnName="id") 14 | private long id; 15 | 16 | @OneToOneColumn(columnName="content") 17 | private String content; 18 | 19 | @OneToOneColumn(columnName="articleId") 20 | private long articleId; 21 | 22 | @OneToOneColumn(columnName="replyId") 23 | private long replyId; 24 | 25 | @OneToOneColumn(columnName="username") 26 | private String username; 27 | 28 | @OneToOneColumn(columnName="createOn") 29 | private Date createOn; 30 | public Discuss(){} 31 | public Discuss(long id,String content,long articleid,long replyid,String username,Date createon){ 32 | this.id = id; 33 | this.content = content; 34 | this.articleId = articleid; 35 | this.replyId = replyid; 36 | this.username = username; 37 | this.createOn = createon; 38 | markNew(); 39 | } 40 | 41 | public long getDiscussId() { 42 | // TODO Auto-generated method stub 43 | return this.id; 44 | } 45 | 46 | public String getDiscussContent() { 47 | // TODO Auto-generated method stub 48 | return this.content; 49 | } 50 | 51 | public long getReplyId() { 52 | // TODO Auto-generated method stub 53 | return this.replyId; 54 | } 55 | 56 | public String getUserName() { 57 | // TODO Auto-generated method stub 58 | return this.username; 59 | } 60 | 61 | public Date getCreateOn() { 62 | // TODO Auto-generated method stub 63 | return this.createOn; 64 | } 65 | 66 | public long getArticleId() { 67 | // TODO Auto-generated method stub 68 | return this.articleId; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/article/DiscussComparator.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.article; 2 | 3 | import java.util.Comparator; 4 | 5 | public class DiscussComparator implements Comparator { 6 | 7 | @Override 8 | public int compare(Discuss discuss1, Discuss discuss2) { 9 | // TODO Auto-generated method stub 10 | if (discuss2 == null) { 11 | return 1; 12 | } 13 | if (discuss1 == null) { 14 | return -1; 15 | } 16 | Discuss d1 = (Discuss) discuss1; 17 | Discuss d2 = (Discuss) discuss2; 18 | if (d1.getDiscussId() > d2.getDiscussId()) { 19 | return 1; 20 | } else if (d1.getDiscussId() == d2.getDiscussId()) { 21 | return 0; 22 | } else { 23 | return -1; 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/article/DiscussNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.article; 2 | 3 | public class DiscussNotFoundException extends RuntimeException{ 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = -1488000519586378237L; 9 | 10 | public DiscussNotFoundException(){ 11 | super("Discuss not Found!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/repository/ArticleRepository.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.repository; 2 | 3 | import com.huxuemin.xblog.domain.article.Article; 4 | 5 | public class ArticleRepository extends IRepository
{ 6 | 7 | public ArticleRepository(){ 8 | super(Article.class); 9 | } 10 | 11 | @Override 12 | protected boolean comparePrimaryKeyPolicy(Article domainObject, Object primaryKey) { 13 | // TODO Auto-generated method stub 14 | if(domainObject.getArticleId() == Long.valueOf(String.valueOf(primaryKey))){ 15 | return true; 16 | } 17 | return false; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/repository/IRepository.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.repository; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | import com.huxuemin.xblog.database.mapper.MapperRegister; 8 | import com.huxuemin.xblog.infrastructure.DomainObject; 9 | 10 | public abstract class IRepository { 11 | protected List domainObjects = new ArrayList(); 12 | protected final Class klass; 13 | 14 | protected IRepository(Class klass){ 15 | this.klass = klass; 16 | init(); 17 | } 18 | 19 | public T get(Object primaryKey){ 20 | for(Iterator it = domainObjects.iterator();it.hasNext();){ 21 | T domainObject = it.next(); 22 | if(comparePrimaryKeyPolicy(domainObject,primaryKey)){ 23 | return domainObject; 24 | } 25 | } 26 | T domainObject = (T) MapperRegister.getMapper(klass).findObjectByPrimaryKey(primaryKey); 27 | if(domainObject != null){ 28 | add(domainObject); 29 | } 30 | // System.out.println(domainObject); 31 | return domainObject; 32 | } 33 | 34 | public List getAll(){ 35 | if(domainObjects.isEmpty()){ 36 | List result = MapperRegister.getMapper(klass).findObjectWhere(" 1 = 1"); 37 | if(!result.isEmpty()){ 38 | domainObjects.addAll(result); 39 | } 40 | } 41 | return domainObjects; 42 | } 43 | 44 | public void delete(T obj){ 45 | synchronized(IRepository.this){ 46 | if(domainObjects.contains(obj)){ 47 | domainObjects.remove(obj); 48 | obj.delete(); 49 | } 50 | } 51 | } 52 | 53 | // public boolean isExist(T obj){ 54 | // synchronized(IRepository.this){ 55 | // return domainObjects.contains(obj); 56 | // } 57 | // } 58 | 59 | public boolean isExistByPrimaryKey(Object primaryKey){ 60 | synchronized(IRepository.this){ 61 | T domainObject = get(primaryKey); 62 | if(domainObject != null){ 63 | return true; 64 | }else{ 65 | return false; 66 | } 67 | } 68 | } 69 | 70 | public void add(T obj){ 71 | synchronized(IRepository.this){ 72 | if(!domainObjects.contains(obj)){ 73 | domainObjects.add(obj); 74 | } 75 | } 76 | } 77 | 78 | protected abstract boolean comparePrimaryKeyPolicy(T domainObject,Object primaryKey); 79 | protected void init(){} 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/repository/RepositoryRegister.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.repository; 2 | 3 | public class RepositoryRegister { 4 | public static UserRepository userR = new UserRepository(); 5 | public static RoleRepository roleR = new RoleRepository(); 6 | public static ArticleRepository articleR = new ArticleRepository(); 7 | 8 | public static UserRepository getUserRepository(){ 9 | return userR; 10 | } 11 | 12 | public static RoleRepository getRoleRepository(){ 13 | return roleR; 14 | } 15 | 16 | public static ArticleRepository getArticleRepository(){ 17 | return articleR; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/repository/RoleRepository.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.repository; 2 | 3 | import com.huxuemin.xblog.domain.user.Role; 4 | 5 | /** 6 | * @author huxuemin 2016��8��23�� 7 | * 8 | */ 9 | public class RoleRepository extends IRepository { 10 | 11 | public RoleRepository() { 12 | super(Role.class); 13 | } 14 | 15 | @Override 16 | protected boolean comparePrimaryKeyPolicy(Role domainObject, Object primaryKey) { 17 | // TODO Auto-generated method stub 18 | if (domainObject.getName().equals(String.valueOf(primaryKey))) { 19 | return true; 20 | } 21 | return false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/repository/UnitOfWork.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.repository; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import java.util.ArrayList; 6 | import java.util.Iterator; 7 | import java.util.List; 8 | 9 | import com.huxuemin.xblog.database.DBConnectionFactory; 10 | import com.huxuemin.xblog.database.mapper.MapperRegister; 11 | import com.huxuemin.xblog.database.mapper.SqlTransactionException; 12 | import com.huxuemin.xblog.infrastructure.DomainObject; 13 | 14 | public class UnitOfWork { 15 | 16 | private static ThreadLocal current = new ThreadLocal(); 17 | 18 | private List newObjects = new ArrayList(); 19 | private List dirtyObjects = new ArrayList(); 20 | private List removedObjects = new ArrayList(); 21 | private Connection conn; 22 | 23 | private UnitOfWork() { 24 | conn = DBConnectionFactory.getConnection(); 25 | try { 26 | if(conn!=null && conn.getAutoCommit()){ 27 | conn.setAutoCommit(false); 28 | } 29 | } catch (SQLException e) { 30 | // TODO Auto-generated catch block 31 | e.printStackTrace(); 32 | } 33 | } 34 | 35 | public void registerNew(DomainObject obj) { 36 | if (obj != null && !dirtyObjects.contains(obj) && !removedObjects.contains(obj) && !newObjects.contains(obj)) { 37 | newObjects.add(obj); 38 | } 39 | } 40 | 41 | public void registerDirty(DomainObject obj) { 42 | if (obj != null && !dirtyObjects.contains(obj) && !removedObjects.contains(obj) && !newObjects.contains(obj)) { 43 | dirtyObjects.add(obj); 44 | } 45 | } 46 | 47 | public void registerRemoved(DomainObject obj) { 48 | if (obj != null) { 49 | if (!newObjects.remove(obj)) { 50 | dirtyObjects.remove(obj); 51 | if (!removedObjects.contains(obj)) { 52 | removedObjects.add(obj); 53 | } 54 | } 55 | } 56 | } 57 | 58 | public static void newCurrent() { 59 | setCurrent(new UnitOfWork()); 60 | } 61 | 62 | public static void setCurrent(UnitOfWork uow) { 63 | current.set(uow); 64 | } 65 | 66 | public static UnitOfWork getCurrent() { 67 | return current.get(); 68 | } 69 | 70 | public Connection getConnection() { 71 | return conn; 72 | } 73 | 74 | public void commit() { 75 | insertNew(); 76 | UpdateDirty(); 77 | deleteRemoved(); 78 | try { 79 | conn.commit(); 80 | } catch (SQLException e) { 81 | // TODO Auto-generated catch block 82 | try { 83 | conn.rollback(); 84 | } catch (SQLException e1) { 85 | // TODO Auto-generated catch block 86 | e1.printStackTrace(); 87 | } 88 | throw new SqlTransactionException(e.toString()); 89 | } finally { 90 | try { 91 | conn.close(); 92 | } catch (SQLException e) { 93 | // TODO Auto-generated catch block 94 | e.printStackTrace(); 95 | } 96 | } 97 | current.remove(); 98 | } 99 | 100 | private void insertNew() { 101 | Iterator objects = newObjects.iterator(); 102 | while (objects.hasNext()) { 103 | DomainObject obj = objects.next(); 104 | MapperRegister.getMapper(obj.getClass()).insert(obj); 105 | } 106 | } 107 | 108 | private void UpdateDirty() { 109 | Iterator objects = dirtyObjects.iterator(); 110 | while (objects.hasNext()) { 111 | DomainObject obj = objects.next(); 112 | MapperRegister.getMapper(obj.getClass()).update(obj); 113 | } 114 | } 115 | 116 | private void deleteRemoved() { 117 | Iterator objects = removedObjects.iterator(); 118 | while (objects.hasNext()) { 119 | DomainObject obj = objects.next(); 120 | MapperRegister.getMapper(obj.getClass()).delete(obj); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.repository; 2 | 3 | import com.huxuemin.xblog.domain.user.User; 4 | 5 | /** 6 | * @author huxuemin 2016��8��23�� 7 | * 8 | */ 9 | public class UserRepository extends IRepository{ 10 | 11 | public UserRepository(){ 12 | super(User.class); 13 | } 14 | 15 | @Override 16 | protected boolean comparePrimaryKeyPolicy(User domainObject, Object primaryKey) { 17 | // TODO Auto-generated method stub 18 | if(domainObject.getUserName().equals(String.valueOf(primaryKey))){ 19 | return true; 20 | } 21 | return false; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/user/Role.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.user; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | import com.huxuemin.xblog.database.mapper.OneToManyColumn; 8 | import com.huxuemin.xblog.database.mapper.PrimaryKeyColumn; 9 | import com.huxuemin.xblog.database.mapper.Table; 10 | import com.huxuemin.xblog.infrastructure.AuthConstant; 11 | import com.huxuemin.xblog.infrastructure.DomainObject; 12 | 13 | @Table(name = "ROLES") 14 | public class Role extends DomainObject { 15 | 16 | @PrimaryKeyColumn(columnName = "name") 17 | private String name; 18 | 19 | // private List constantAuth; 20 | 21 | @OneToManyColumn(columnName = "authority", foreignKeyColumnName = "name", foreigntableName = "rolesauth") 22 | private List strintAuth; 23 | 24 | public Role() { 25 | } 26 | 27 | public Role(String name) { 28 | this.name = name; 29 | } 30 | 31 | private List constantAuth() { 32 | List constantAuth = new ArrayList(); 33 | if (strintAuth != null) { 34 | Iterator it = strintAuth.iterator(); 35 | while (it.hasNext()) { 36 | constantAuth.add(AuthConstant.valueOf(it.next())); 37 | } 38 | } 39 | return constantAuth; 40 | } 41 | 42 | public List getAuthList() { 43 | return constantAuth(); 44 | } 45 | 46 | public String getName() { 47 | return this.name; 48 | } 49 | 50 | public void addAuth(AuthConstant auth) { 51 | if (!hasAuth(auth)) { 52 | strintAuth.add(auth.toString()); 53 | } 54 | } 55 | 56 | public void removeAuth(AuthConstant auth) { 57 | Iterator it = strintAuth.iterator(); 58 | while (it.hasNext()) { 59 | if (it.next().equals(auth.toString())) { 60 | it.remove(); 61 | break; 62 | } 63 | } 64 | } 65 | 66 | public boolean hasAuth(AuthConstant auth) { 67 | boolean result = false; 68 | Iterator it = strintAuth.iterator(); 69 | while ((!result) && it.hasNext()) { 70 | result = (it.next().equals(auth.toString())); 71 | } 72 | return result; 73 | } 74 | 75 | @Override 76 | public int hashCode() { 77 | final int prime = 31; 78 | int result = 1; 79 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 80 | return result; 81 | } 82 | 83 | @Override 84 | public boolean equals(Object obj) { 85 | if (this == obj) 86 | return true; 87 | if (obj == null) 88 | return false; 89 | if (getClass() != obj.getClass()) 90 | return false; 91 | Role other = (Role) obj; 92 | if (name == null) { 93 | if (other.name != null) 94 | return false; 95 | } else if (!name.equals(other.name)) 96 | return false; 97 | return true; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/user/UserFactory.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.user; 2 | 3 | import com.huxuemin.xblog.domain.repository.RepositoryRegister; 4 | import com.huxuemin.xblog.infrastructure.dtos.UserInfoDTO; 5 | import com.huxuemin.xblog.infrastructure.tools.IDCreateFactory; 6 | import com.huxuemin.xblog.infrastructure.tools.MD5Tools; 7 | 8 | public class UserFactory { 9 | //static long userid = 100; 10 | //hashedpassword: 8fe73152a9ffdde3cde40d1120c3c02b 11 | //salt: 2d07a6f758d2fcac6a88bade6e915d4c 12 | 13 | public static long getId(){ 14 | return IDCreateFactory.getId(); 15 | } 16 | 17 | /** 18 | * ����һ���û� 19 | * @param username �û��� 20 | * @param password ���� 21 | * @return �û� 22 | */ 23 | public static User createUser(String username,String password){ 24 | User user = new User(username); 25 | String salt = ""; 26 | String hashedPassword = ""; 27 | try { 28 | salt = MD5Tools.md5Encode(username + String.valueOf(System.currentTimeMillis())); 29 | hashedPassword = MD5Tools.md5Encode(salt + password); 30 | } catch (Exception e) { 31 | // TODO Auto-generated catch block 32 | e.printStackTrace(); 33 | } 34 | user.setSalt(salt); 35 | user.setHashedPassword(hashedPassword); 36 | user.addRole(RepositoryRegister.getRoleRepository().get("user")); 37 | return user; 38 | } 39 | 40 | public static Role createRole(String rolename){ 41 | return new Role(rolename); 42 | } 43 | 44 | public static void modifyUserInfo(UserInfoDTO userInfoDTO){ 45 | User infoUser = RepositoryRegister.getUserRepository().get(userInfoDTO.getUserName()); 46 | infoUser.setFirstname(userInfoDTO.getFirstName()); 47 | infoUser.setLastname(userInfoDTO.getLastName()); 48 | infoUser.setLang(userInfoDTO.getLang()); 49 | infoUser.setCountry(userInfoDTO.getCountry()); 50 | infoUser.setProfession(userInfoDTO.getProfession()); 51 | infoUser.setSex(userInfoDTO.getSex()); 52 | infoUser.setBirthday(userInfoDTO.getBirthday()); 53 | infoUser.setProfile(userInfoDTO.getProfile()); 54 | infoUser.setQQ(userInfoDTO.getQQ()); 55 | infoUser.setPhoneNum(userInfoDTO.getPhoneNum()); 56 | infoUser.setEmail(userInfoDTO.getEmail()); 57 | infoUser.setAddress(userInfoDTO.getAddress()); 58 | infoUser.setWechat(userInfoDTO.getWechat()); 59 | } 60 | 61 | public static UserInfoDTO createUserInfoDTO(User usersinfo){ 62 | UserPublicInfo publicInfo = usersinfo.getPublicInfo(); 63 | UserInfoDTO dto = new UserInfoDTO(publicInfo.getUsername()); 64 | dto.setFirstName(publicInfo.getFirstname()); 65 | dto.setLastName(publicInfo.getLastname()); 66 | dto.setLang(publicInfo.getLang()); 67 | dto.setCountry(publicInfo.getCountry()); 68 | dto.setProfession(publicInfo.getProfession()); 69 | dto.setSex(publicInfo.getSex()); 70 | dto.setBirthday(publicInfo.getBirthday()); 71 | dto.setProfile(publicInfo.getProfile()); 72 | return dto; 73 | } 74 | 75 | public static UserInfoDTO createFullUserInfoDTO(User usersinfo){ 76 | UserInfoDTO dto = createUserInfoDTO(usersinfo); 77 | UserPrivateInfo privateInfo = usersinfo.getPrivateInfo(); 78 | dto.setQQ(privateInfo.getQQ()); 79 | dto.setPhoneNum(privateInfo.getPhoneNum()); 80 | dto.setEmail(privateInfo.getEmail()); 81 | dto.setAddress(privateInfo.getAddress()); 82 | dto.setWechat(privateInfo.getWechat()); 83 | return dto; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/user/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.user; 2 | 3 | public class UserNotFoundException extends RuntimeException{ 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = -7671096847221755853L; 9 | 10 | public UserNotFoundException(){ 11 | super("User not found!"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/user/UserPrivateInfo.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.user; 2 | 3 | import com.huxuemin.xblog.database.mapper.OneToOneColumn; 4 | import com.huxuemin.xblog.database.mapper.PrimaryKeyColumn; 5 | import com.huxuemin.xblog.database.mapper.Table; 6 | import com.huxuemin.xblog.infrastructure.DomainObject; 7 | 8 | @Table(name="userprivateinfo") 9 | public class UserPrivateInfo extends DomainObject{ 10 | 11 | @PrimaryKeyColumn(columnName="username") 12 | private String username; 13 | 14 | @OneToOneColumn(columnName="phoneNum") 15 | private String phoneNum; 16 | 17 | @OneToOneColumn(columnName="address") 18 | private String address; 19 | 20 | @OneToOneColumn(columnName="qq") 21 | private String QQ; 22 | 23 | @OneToOneColumn(columnName="wechat") 24 | private String wechat; 25 | 26 | @OneToOneColumn(columnName="email") 27 | private String Email; 28 | 29 | public UserPrivateInfo(){ 30 | } 31 | public UserPrivateInfo(String username){ 32 | this.username = username; 33 | markNew(); 34 | } 35 | 36 | public String getPhoneNum() { 37 | return phoneNum; 38 | } 39 | 40 | public void setPhoneNum(String phoneNum) { 41 | this.phoneNum = phoneNum; 42 | markDirty(); 43 | } 44 | 45 | public String getAddress() { 46 | return address; 47 | } 48 | 49 | public void setAddress(String address) { 50 | this.address = address; 51 | markDirty(); 52 | } 53 | 54 | public String getQQ() { 55 | return QQ; 56 | } 57 | 58 | public void setQQ(String qQ) { 59 | QQ = qQ; 60 | markDirty(); 61 | } 62 | 63 | public String getWechat() { 64 | return wechat; 65 | } 66 | 67 | public void setWechat(String wechat) { 68 | this.wechat = wechat; 69 | markDirty(); 70 | } 71 | 72 | public String getEmail() { 73 | return Email; 74 | } 75 | 76 | public void setEmail(String email) { 77 | Email = email; 78 | markDirty(); 79 | } 80 | 81 | public String getUsername() { 82 | return username; 83 | } 84 | 85 | public void setUsername(String username) { 86 | this.username = username; 87 | markDirty(); 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/user/UserPublicInfo.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.user; 2 | 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | 7 | import com.huxuemin.xblog.database.mapper.OneToOneColumn; 8 | import com.huxuemin.xblog.database.mapper.PrimaryKeyColumn; 9 | import com.huxuemin.xblog.database.mapper.Table; 10 | import com.huxuemin.xblog.infrastructure.DomainObject; 11 | 12 | @Table(name="userpublicinfo") 13 | public class UserPublicInfo extends DomainObject{ 14 | 15 | @PrimaryKeyColumn(columnName="username") 16 | private String username; 17 | 18 | @OneToOneColumn(columnName="firstname") 19 | private String firstname; 20 | 21 | @OneToOneColumn(columnName="lastname") 22 | private String lastname; 23 | 24 | @OneToOneColumn(columnName="lang") 25 | private String lang; 26 | 27 | @OneToOneColumn(columnName="profession") 28 | private String profession; 29 | 30 | @OneToOneColumn(columnName="country") 31 | private String country; 32 | 33 | @OneToOneColumn(columnName="sex") 34 | private String sex; 35 | 36 | @OneToOneColumn(columnName="birthday") 37 | private Date birthday; 38 | 39 | @OneToOneColumn(columnName="profile") 40 | private String profile; 41 | 42 | public UserPublicInfo(){} 43 | 44 | public UserPublicInfo(String username){ 45 | this.username = username; 46 | try { 47 | birthday = new SimpleDateFormat("yyyy-MM-dd").parse("1987-01-01"); 48 | } catch (ParseException e) { 49 | // TODO Auto-generated catch block 50 | e.printStackTrace(); 51 | } 52 | markNew(); 53 | } 54 | 55 | public String getFirstname() { 56 | return firstname; 57 | } 58 | 59 | public void setFirstname(String firstname) { 60 | this.firstname = firstname; 61 | markDirty(); 62 | } 63 | 64 | public String getLastname() { 65 | return lastname; 66 | } 67 | 68 | public void setLastname(String lastname) { 69 | this.lastname = lastname; 70 | markDirty(); 71 | } 72 | 73 | public String getLang() { 74 | return lang; 75 | } 76 | 77 | public void setLang(String lang) { 78 | this.lang = lang; 79 | markDirty(); 80 | } 81 | 82 | public String getProfession() { 83 | return profession; 84 | } 85 | 86 | public void setProfession(String profession) { 87 | this.profession = profession; 88 | markDirty(); 89 | } 90 | 91 | public String getSex() { 92 | return sex; 93 | } 94 | 95 | public void setSex(String sex) { 96 | this.sex = sex; 97 | markDirty(); 98 | } 99 | 100 | public Date getBirthday() { 101 | return birthday; 102 | } 103 | 104 | public void setBirthday(Date birthday) { 105 | this.birthday = birthday; 106 | markDirty(); 107 | } 108 | 109 | public String getProfile() { 110 | return profile; 111 | } 112 | 113 | public void setProfile(String profile) { 114 | this.profile = profile; 115 | markDirty(); 116 | } 117 | 118 | public String getUsername() { 119 | return username; 120 | } 121 | 122 | public void setUsername(String username) { 123 | this.username = username; 124 | markDirty(); 125 | } 126 | 127 | public String getCountry() { 128 | return country; 129 | } 130 | 131 | public void setCountry(String country) { 132 | this.country = country; 133 | markDirty(); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/domain/user/UserVerifyFailedException.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.domain.user; 2 | 3 | public class UserVerifyFailedException extends RuntimeException { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = -8921418915486461985L; 9 | 10 | public UserVerifyFailedException(){ 11 | super("User Verify failed!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/AuthConstant.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | /** 4 | * @author huxuemin 5 | * 6 | */ 7 | public enum AuthConstant { 8 | 9 | USER_MANAGER(101,"user management rights"), 10 | 11 | ROLE_MANAGER(102,"role managerment rights"), 12 | 13 | ARTICLE_MANAGER(103,"article managerment rights"), 14 | 15 | DISCUSS_MANAGER(104,"discuss managerment rights"), 16 | 17 | PUBLIC_DISCUSS(201,"publish discuss rights"), 18 | 19 | MANAGE_PAGE(301,"access manage page rights"); 20 | 21 | int num; 22 | 23 | String desc; 24 | 25 | private AuthConstant(int num,String desc){ 26 | this.num = num; 27 | this.desc = desc; 28 | } 29 | 30 | public int numOfAuth(){ 31 | return num; 32 | } 33 | 34 | public String descOfAuth(){ 35 | return desc; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/AuthException.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | public class AuthException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 8121219522271194298L; 6 | private AuthConstant auth; 7 | 8 | public AuthException(AuthConstant ac){ 9 | super("non-Auth:" + ac.descOfAuth()); 10 | this.auth = ac; 11 | } 12 | 13 | public AuthConstant getAuthConstant(){ 14 | return this.auth; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/DomainObject.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | import com.huxuemin.xblog.domain.repository.UnitOfWork; 4 | 5 | public abstract class DomainObject { 6 | 7 | protected void markNew(){ 8 | UnitOfWork uok = UnitOfWork.getCurrent(); 9 | if(uok != null){ 10 | uok.registerNew(this); 11 | } 12 | } 13 | 14 | protected void markClean(){ 15 | 16 | } 17 | 18 | protected void markDirty(){ 19 | UnitOfWork uok = UnitOfWork.getCurrent(); 20 | if(uok != null){ 21 | uok.registerDirty(this); 22 | } 23 | } 24 | 25 | protected void markRemoved(){ 26 | UnitOfWork uok = UnitOfWork.getCurrent(); 27 | if(uok != null){ 28 | uok.registerRemoved(this); 29 | } 30 | } 31 | 32 | public void delete(){ 33 | markRemoved(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/DoubleNodeStruct.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | public class DoubleNodeStruct { 4 | private DoubleNodeStruct prev = null; 5 | private DoubleNodeStruct next = null; 6 | private T data = null; 7 | 8 | public DoubleNodeStruct(){ 9 | } 10 | 11 | public DoubleNodeStruct(T t){ 12 | data = t; 13 | } 14 | 15 | public T getNodeData(){ 16 | return data; 17 | } 18 | 19 | public void setNodeData(T t){ 20 | data = t; 21 | } 22 | 23 | public boolean hasPrevNode(){ 24 | return prev != null; 25 | } 26 | 27 | public DoubleNodeStruct getPrevNode(){ 28 | return prev; 29 | } 30 | 31 | public void setPrevNode(DoubleNodeStruct dn){ 32 | prev = dn; 33 | } 34 | 35 | public boolean hasNextNode(){ 36 | return next != null; 37 | } 38 | 39 | public DoubleNodeStruct getNextNode(){ 40 | return next; 41 | } 42 | 43 | public void setNextNode(DoubleNodeStruct dn){ 44 | next = dn; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/ErrorMessage.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | import javax.xml.bind.annotation.XmlAccessType; 4 | import javax.xml.bind.annotation.XmlAccessorType; 5 | import javax.xml.bind.annotation.XmlElement; 6 | import javax.xml.bind.annotation.XmlRootElement; 7 | import javax.xml.bind.annotation.XmlType; 8 | 9 | import com.google.gson.annotations.SerializedName; 10 | 11 | @XmlAccessorType(XmlAccessType.FIELD) 12 | @XmlRootElement(name = "error") 13 | @XmlType(name = "error", propOrder = { "code", "message" }) 14 | public class ErrorMessage { 15 | 16 | @XmlElement 17 | @SerializedName("code") 18 | private int code; 19 | 20 | @XmlElement 21 | @SerializedName("message") 22 | private String message; 23 | 24 | public ErrorMessage(){ 25 | this.code = -1; 26 | this.message = "unKnow Error!"; 27 | } 28 | 29 | public ErrorMessage(int code, String message) { 30 | this.code = code; 31 | this.message = message; 32 | } 33 | 34 | public int getCode() { 35 | return this.code; 36 | } 37 | 38 | public String getMessage() { 39 | return message; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/RegexConstant.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | public class RegexConstant { 4 | //^[a-zA-Z][a-zA-Z0-9_]*$ 5 | public static final String USERNAME = "^[a-zA-Z][a-zA-Z0-9_]*$"; 6 | //^[a-zA-Z](?:[\S]*[0-9_])+[\S]*$ 7 | public static final String PASSWORD = "^[a-zA-Z](?:[\\S]*[0-9_])+[\\S]*$"; 8 | //\d{3}-\d{8}|\d{4}-\{7,8} 9 | public static final String PHONE = "\\d{3}-\\d{8}|\\d{4}-\\{7,8}"; 10 | //[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])? 11 | public static final String EMAIL = "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?"; 12 | //[1-9][0-9]{4,} 13 | public static final String QQ = "[1-9][0-9]{4,}"; 14 | // < : < < 15 | public static final String HTMLLT = "<(?!br)"; 16 | // > : > > 17 | public static final String HTMLGT = "(?"; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/RigheNodeStruct.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | public class RigheNodeStruct { 4 | private RigheNodeStruct next = null; 5 | private T data = null; 6 | 7 | public RigheNodeStruct(){ 8 | } 9 | 10 | public RigheNodeStruct(T t){ 11 | data = t; 12 | } 13 | 14 | public T getNodeData(){ 15 | return data; 16 | } 17 | 18 | public void setNodeData(T t){ 19 | data = t; 20 | } 21 | 22 | public boolean hasNextNode(){ 23 | return next != null; 24 | } 25 | 26 | public RigheNodeStruct getNextNode(){ 27 | return next; 28 | } 29 | 30 | public void setNextNode(RigheNodeStruct dn){ 31 | next = dn; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/SessionConstant.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | public class SessionConstant { 4 | public final static String USERNAME = "username"; 5 | public final static String PASSWORD = "password"; 6 | public final static String LASTREFRESHTIME = "lastRefreshTime"; 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/SuccessMessage.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure; 2 | 3 | import javax.xml.bind.annotation.XmlAccessType; 4 | import javax.xml.bind.annotation.XmlAccessorType; 5 | import javax.xml.bind.annotation.XmlElement; 6 | import javax.xml.bind.annotation.XmlRootElement; 7 | import javax.xml.bind.annotation.XmlType; 8 | 9 | import com.google.gson.annotations.SerializedName; 10 | 11 | @XmlAccessorType(XmlAccessType.FIELD) 12 | @XmlRootElement(name = "success") 13 | @XmlType(name = "success", propOrder = { "code", "message" }) 14 | public class SuccessMessage { 15 | 16 | @XmlElement 17 | @SerializedName("code") 18 | private int code; 19 | 20 | @XmlElement 21 | @SerializedName("message") 22 | private String message; 23 | 24 | public SuccessMessage(){ 25 | this.code = -1; 26 | this.message = "Successful!"; 27 | } 28 | 29 | public SuccessMessage(int code, String message) { 30 | this.code = code; 31 | this.message = message; 32 | } 33 | 34 | public int getCode() { 35 | return this.code; 36 | } 37 | 38 | public String getMessage() { 39 | return message; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/dtos/ArticleDTO.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.dtos; 2 | 3 | import javax.xml.bind.annotation.XmlAccessType; 4 | import javax.xml.bind.annotation.XmlAccessorType; 5 | import javax.xml.bind.annotation.XmlElement; 6 | import javax.xml.bind.annotation.XmlRootElement; 7 | import javax.xml.bind.annotation.XmlType; 8 | 9 | import com.google.gson.annotations.SerializedName; 10 | 11 | @XmlAccessorType(XmlAccessType.FIELD) 12 | @XmlRootElement(name = "article") 13 | @XmlType(propOrder = { "id", "title", "content" }) 14 | public class ArticleDTO { 15 | 16 | @XmlElement 17 | @SerializedName("artileId") 18 | private long id; 19 | 20 | @XmlElement 21 | @SerializedName("articleTitle") 22 | private String title; 23 | 24 | @XmlElement 25 | @SerializedName("articleContent") 26 | private String content; 27 | 28 | public long getArticleId() { 29 | return id; 30 | } 31 | 32 | public void setArtileId(long artileId) { 33 | this.id = artileId; 34 | } 35 | 36 | public String getArticleTitle() { 37 | return title; 38 | } 39 | 40 | public void setArticleTitle(String title) { 41 | this.title = title; 42 | } 43 | 44 | public String getArticleContent() { 45 | return content; 46 | } 47 | 48 | public void setArticleContent(String articlecontent) { 49 | this.content = articlecontent; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/dtos/ArticleSummaryDTO.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.dtos; 2 | 3 | import javax.xml.bind.annotation.XmlAccessType; 4 | import javax.xml.bind.annotation.XmlAccessorType; 5 | import javax.xml.bind.annotation.XmlElement; 6 | import javax.xml.bind.annotation.XmlRootElement; 7 | import javax.xml.bind.annotation.XmlType; 8 | 9 | import com.google.gson.annotations.SerializedName; 10 | 11 | @XmlAccessorType(XmlAccessType.FIELD) 12 | @XmlRootElement(name = "article") 13 | @XmlType(propOrder = { "id", "title" }) 14 | public class ArticleSummaryDTO { 15 | 16 | @XmlElement 17 | @SerializedName("id") 18 | private long id; 19 | 20 | @XmlElement 21 | @SerializedName("title") 22 | private String title; 23 | 24 | public long getId() { 25 | return id; 26 | } 27 | 28 | public void setId(long id) { 29 | this.id = id; 30 | } 31 | 32 | public String getTitle() { 33 | return title; 34 | } 35 | 36 | public void setTitle(String title) { 37 | this.title = title; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/dtos/ArticleSummaryDTOList.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.dtos; 2 | 3 | import java.util.List; 4 | 5 | import javax.xml.bind.annotation.XmlAccessType; 6 | import javax.xml.bind.annotation.XmlAccessorType; 7 | import javax.xml.bind.annotation.XmlElement; 8 | import javax.xml.bind.annotation.XmlRootElement; 9 | import javax.xml.bind.annotation.XmlType; 10 | 11 | @XmlRootElement(name="articles") 12 | @XmlAccessorType(XmlAccessType.FIELD) 13 | @XmlType(propOrder = { "articles" }) 14 | public class ArticleSummaryDTOList { 15 | 16 | @XmlElement(name="article") 17 | private List articles; 18 | 19 | public List getArticles() { 20 | return articles; 21 | } 22 | 23 | public void setArticles(List articles) { 24 | this.articles = articles; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/dtos/DiscussDTO.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.dtos; 2 | 3 | import java.util.Date; 4 | 5 | import javax.xml.bind.annotation.XmlAccessType; 6 | import javax.xml.bind.annotation.XmlAccessorType; 7 | import javax.xml.bind.annotation.XmlElement; 8 | import javax.xml.bind.annotation.XmlRootElement; 9 | import javax.xml.bind.annotation.XmlType; 10 | 11 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 12 | import com.google.gson.annotations.SerializedName; 13 | import com.huxuemin.xblog.infrastructure.tools.CustomDateSerializer; 14 | 15 | @XmlAccessorType(XmlAccessType.FIELD) 16 | @XmlRootElement(name = "discuss") 17 | @XmlType(propOrder = { "id", "content", "replyUserName", "replyDisName", "owerUserName", 18 | "owerDisplayName", "createOn" }) 19 | public class DiscussDTO { 20 | 21 | @XmlElement 22 | @SerializedName("id") 23 | private long id; 24 | 25 | @XmlElement 26 | @SerializedName("content") 27 | private String content; 28 | 29 | @XmlElement 30 | @SerializedName("replyUserName") 31 | private String replyUserName; 32 | 33 | @XmlElement 34 | @SerializedName("replyDisName") 35 | private String replyDisName; 36 | 37 | @XmlElement 38 | @SerializedName("owerUserName") 39 | private String owerUserName; 40 | 41 | @XmlElement 42 | @SerializedName("owerDisplayName") 43 | private String owerDisplayName; 44 | 45 | @XmlElement 46 | @SerializedName("createOn") 47 | private Date createOn; 48 | 49 | public long getId() { 50 | return id; 51 | } 52 | 53 | public void setId(long id) { 54 | this.id = id; 55 | } 56 | 57 | public DiscussDTO(){ 58 | } 59 | 60 | public DiscussDTO(long id) { 61 | this.id = id; 62 | } 63 | 64 | public String getContent() { 65 | return content; 66 | } 67 | 68 | public void setContent(String content) { 69 | this.content = content; 70 | } 71 | 72 | public String getReplyUserName() { 73 | return replyUserName; 74 | } 75 | 76 | public void setReplyUserName(String replyUserName) { 77 | this.replyUserName = replyUserName; 78 | } 79 | 80 | public String getOwerUserName() { 81 | return owerUserName; 82 | } 83 | 84 | public void setOwerUserName(String owerUserName) { 85 | this.owerUserName = owerUserName; 86 | } 87 | 88 | @JsonSerialize(using = CustomDateSerializer.class) 89 | public Date getCreateOn() { 90 | return createOn; 91 | } 92 | 93 | public void setCreateOn(Date createOn) { 94 | this.createOn = createOn; 95 | } 96 | 97 | public String getReplyDisName() { 98 | return replyDisName; 99 | } 100 | 101 | public void setReplyDisName(String replyDisName) { 102 | this.replyDisName = replyDisName; 103 | } 104 | 105 | public String getOwerDisplayName() { 106 | return owerDisplayName; 107 | } 108 | 109 | public void setOwerDisplayName(String owerDisplayName) { 110 | this.owerDisplayName = owerDisplayName; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/dtos/DiscussDTOList.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.dtos; 2 | 3 | import java.util.List; 4 | 5 | import javax.xml.bind.annotation.XmlAccessType; 6 | import javax.xml.bind.annotation.XmlAccessorType; 7 | import javax.xml.bind.annotation.XmlElement; 8 | import javax.xml.bind.annotation.XmlRootElement; 9 | import javax.xml.bind.annotation.XmlType; 10 | 11 | @XmlRootElement(name = "discusses") 12 | @XmlAccessorType(XmlAccessType.FIELD) 13 | @XmlType(propOrder = { "discusses" }) 14 | public class DiscussDTOList { 15 | 16 | @XmlElement(name="discuss") 17 | private List discusses; 18 | 19 | public List getDiscusses() { 20 | return discusses; 21 | } 22 | 23 | public void setDiscusses(List discusses) { 24 | this.discusses = discusses; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/dtos/DisplayNameDTO.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.dtos; 2 | 3 | import javax.xml.bind.annotation.XmlAccessType; 4 | import javax.xml.bind.annotation.XmlAccessorType; 5 | import javax.xml.bind.annotation.XmlElement; 6 | import javax.xml.bind.annotation.XmlRootElement; 7 | import javax.xml.bind.annotation.XmlType; 8 | 9 | import com.google.gson.annotations.SerializedName; 10 | 11 | @XmlAccessorType(XmlAccessType.FIELD) 12 | @XmlRootElement(name = "user") 13 | @XmlType(propOrder = { "userName", "displayName" }) 14 | public class DisplayNameDTO { 15 | 16 | @XmlElement 17 | @SerializedName("username") 18 | private String userName; 19 | 20 | @XmlElement 21 | @SerializedName("displayname") 22 | private String displayName; 23 | 24 | public String getUserName() { 25 | return userName; 26 | } 27 | 28 | public void setUserName(String userName) { 29 | this.userName = userName; 30 | } 31 | 32 | public DisplayNameDTO() { 33 | } 34 | 35 | public DisplayNameDTO(String userName) { 36 | this.userName = userName; 37 | } 38 | 39 | public String getDisplayName() { 40 | return displayName; 41 | } 42 | 43 | public void setDisplayName(String displayName) { 44 | this.displayName = displayName; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/dtos/PageDTO.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.dtos; 2 | 3 | import javax.xml.bind.annotation.XmlAccessType; 4 | import javax.xml.bind.annotation.XmlAccessorType; 5 | import javax.xml.bind.annotation.XmlElement; 6 | import javax.xml.bind.annotation.XmlRootElement; 7 | import javax.xml.bind.annotation.XmlType; 8 | 9 | @XmlAccessorType(XmlAccessType.FIELD) 10 | @XmlRootElement(name = "page") 11 | @XmlType(propOrder = { "total" }) 12 | public class PageDTO { 13 | @XmlElement 14 | private int total = 0; 15 | 16 | public PageDTO() { 17 | } 18 | 19 | public PageDTO(int total) { 20 | this.total = total; 21 | } 22 | 23 | public int getTotal() { 24 | return total; 25 | } 26 | 27 | public void setTotal(int total) { 28 | this.total = total; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/dtos/UserInfoDTO.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.dtos; 2 | 3 | import java.util.Date; 4 | 5 | import javax.xml.bind.annotation.XmlAccessType; 6 | import javax.xml.bind.annotation.XmlAccessorType; 7 | import javax.xml.bind.annotation.XmlElement; 8 | import javax.xml.bind.annotation.XmlRootElement; 9 | import javax.xml.bind.annotation.XmlType; 10 | 11 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 12 | import com.google.gson.annotations.SerializedName; 13 | import com.huxuemin.xblog.infrastructure.tools.CustomDateSerializer; 14 | 15 | @XmlAccessorType(XmlAccessType.FIELD) 16 | @XmlRootElement(name = "user") 17 | @XmlType(propOrder = { "userName", "phoneNum", "address", "qq", "wechat", "email", "firstname", "lastname", "lang", 18 | "profession", "country", "sex", "birthday", "profile" }) 19 | public class UserInfoDTO { 20 | 21 | @XmlElement 22 | @SerializedName("username") 23 | private String userName; 24 | 25 | @XmlElement 26 | @SerializedName("phoneNum") 27 | private String phoneNum; 28 | 29 | @XmlElement 30 | @SerializedName("address") 31 | private String address; 32 | 33 | @XmlElement 34 | @SerializedName("qq") 35 | private String qq; 36 | 37 | @XmlElement 38 | @SerializedName("wechat") 39 | private String wechat; 40 | 41 | @XmlElement 42 | @SerializedName("email") 43 | private String email; 44 | 45 | @XmlElement 46 | @SerializedName("firstname") 47 | private String firstname; 48 | 49 | @XmlElement 50 | @SerializedName("lastname") 51 | private String lastname; 52 | 53 | @XmlElement 54 | @SerializedName("lang") 55 | private String lang; 56 | 57 | @XmlElement 58 | @SerializedName("profession") 59 | private String profession; 60 | 61 | @XmlElement 62 | @SerializedName("country") 63 | private String country; 64 | 65 | @XmlElement 66 | @SerializedName("sex") 67 | private String sex; 68 | 69 | @XmlElement 70 | @SerializedName("birthday") 71 | private Date birthday; 72 | 73 | @XmlElement 74 | @SerializedName("profile") 75 | private String profile; 76 | 77 | public UserInfoDTO() { 78 | } 79 | 80 | public UserInfoDTO(String username) { 81 | this.userName = username; 82 | } 83 | 84 | public void setUserName(String username) { 85 | this.userName = username; 86 | } 87 | 88 | public String getUserName() { 89 | return userName; 90 | } 91 | 92 | public String getPhoneNum() { 93 | return phoneNum; 94 | } 95 | 96 | public void setPhoneNum(String phoneNum) { 97 | this.phoneNum = phoneNum; 98 | } 99 | 100 | public String getAddress() { 101 | return address; 102 | } 103 | 104 | public void setAddress(String address) { 105 | this.address = address; 106 | } 107 | 108 | public String getQQ() { 109 | return qq; 110 | } 111 | 112 | public void setQQ(String qQ) { 113 | qq = qQ; 114 | } 115 | 116 | public String getWechat() { 117 | return wechat; 118 | } 119 | 120 | public void setWechat(String wechat) { 121 | this.wechat = wechat; 122 | } 123 | 124 | public String getEmail() { 125 | return email; 126 | } 127 | 128 | public void setEmail(String email) { 129 | this.email = email; 130 | } 131 | 132 | public String getFirstName() { 133 | return firstname; 134 | } 135 | 136 | public void setFirstName(String firstname) { 137 | this.firstname = firstname; 138 | } 139 | 140 | public String getLastName() { 141 | return lastname; 142 | } 143 | 144 | public void setLastName(String lastname) { 145 | this.lastname = lastname; 146 | } 147 | 148 | public String getLang() { 149 | return lang; 150 | } 151 | 152 | public void setLang(String lang) { 153 | this.lang = lang; 154 | } 155 | 156 | public String getProfession() { 157 | return profession; 158 | } 159 | 160 | public void setProfession(String profession) { 161 | this.profession = profession; 162 | } 163 | 164 | public String getCountry() { 165 | return country; 166 | } 167 | 168 | public void setCountry(String country) { 169 | this.country = country; 170 | } 171 | 172 | public String getSex() { 173 | return sex; 174 | } 175 | 176 | public void setSex(String sex) { 177 | this.sex = sex; 178 | } 179 | 180 | @JsonSerialize(using = CustomDateSerializer.class) 181 | public Date getBirthday() { 182 | return birthday; 183 | } 184 | 185 | public void setBirthday(Date birthday) { 186 | this.birthday = birthday; 187 | } 188 | 189 | public String getProfile() { 190 | return profile; 191 | } 192 | 193 | public void setProfile(String profile) { 194 | this.profile = profile; 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/tools/ClasspathPackageScanner.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.tools; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.net.URL; 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | import java.util.jar.JarEntry; 11 | import java.util.jar.JarInputStream; 12 | 13 | public class ClasspathPackageScanner { 14 | // private Logger logger = LoggerFactory.getLogger(ClasspathPackageScanner.class); 15 | 16 | private String basePackage; 17 | private ClassLoader cl; 18 | 19 | /** 20 | * Construct an instance and specify the base package it should scan. 21 | * @param basePackage The base package to scan. 22 | */ 23 | public ClasspathPackageScanner(String basePackage) { 24 | this.basePackage = basePackage; 25 | this.cl = getClass().getClassLoader(); 26 | 27 | } 28 | 29 | /** 30 | * Construct an instance with base package and class loader. 31 | * @param basePackage The base package to scan. 32 | * @param cl Use this class load to locate the package. 33 | */ 34 | public ClasspathPackageScanner(String basePackage, ClassLoader cl) { 35 | this.basePackage = basePackage; 36 | this.cl = cl; 37 | } 38 | 39 | /** 40 | * Get all fully qualified names located in the specified package 41 | * and its sub-package. 42 | * 43 | * @return A list of fully qualified names. 44 | * @throws IOException 45 | */ 46 | public List getFullyQualifiedClassNameList() throws IOException { 47 | // logger.info("开始扫描包{}下的所有类", basePackage); 48 | 49 | return doScan(basePackage, new ArrayList<>()); 50 | } 51 | 52 | /** 53 | * Actually perform the scanning procedure. 54 | * 55 | * @param basePackage 56 | * @param nameList A list to contain the result. 57 | * @return A list of fully qualified names. 58 | * 59 | * @throws IOException 60 | */ 61 | private List doScan(String basePackage, List nameList) throws IOException { 62 | // replace dots with splashes 63 | String splashPath = StringUtil.dotToSplash(basePackage); 64 | 65 | // get file path 66 | URL url = cl.getResource(splashPath); 67 | String filePath = StringUtil.getRootPath(url); 68 | // System.out.println("filePath{"+filePath+ "}"); 69 | 70 | // Get classes in that package. 71 | // If the web server unzips the jar file, then the classes will exist in the form of 72 | // normal file in the directory. 73 | // If the web server does not unzip the jar file, then classes will exist in jar file. 74 | List names = null; // contains the name of the class file. e.g., Apple.class will be stored as "Apple" 75 | if (isJarFile(filePath)) { 76 | // jar file 77 | // if (logger.isDebugEnabled()) { 78 | // logger.debug("{} 是一个JAR包", filePath); 79 | // } 80 | // System.out.println("{"+filePath+ "} 是一个JAR包"); 81 | names = readFromJarFile(filePath, splashPath); 82 | } else { 83 | // directory 84 | // if (logger.isDebugEnabled()) { 85 | // logger.debug("{} 是一个目录", filePath); 86 | // } 87 | // System.out.println("{"+filePath+ "} 是一个目录"); 88 | names = readFromDirectory(filePath); 89 | } 90 | 91 | for (String name : names) { 92 | if (isClassFile(name)) { 93 | //nameList.add(basePackage + "." + StringUtil.trimExtension(name)); 94 | nameList.add(toFullyQualifiedName(name, basePackage)); 95 | } else { 96 | // this is a directory 97 | // check this directory for more classes 98 | // do recursive invocation 99 | doScan(basePackage + "." + name, nameList); 100 | } 101 | } 102 | 103 | // if (logger.isDebugEnabled()) { 104 | // for (String n : nameList) { 105 | // logger.debug("找到{}", n); 106 | // System.out.println("找到{"+n+"}"); 107 | // } 108 | // } 109 | 110 | return nameList; 111 | } 112 | 113 | /** 114 | * Convert short class name to fully qualified name. 115 | * e.g., String -> java.lang.String 116 | */ 117 | private String toFullyQualifiedName(String shortName, String basePackage) { 118 | StringBuilder sb = new StringBuilder(basePackage); 119 | sb.append('.'); 120 | sb.append(StringUtil.trimExtension(shortName)); 121 | 122 | return sb.toString(); 123 | } 124 | 125 | private List readFromJarFile(String jarPath, String splashedPackageName) throws IOException { 126 | // if (logger.isDebugEnabled()) { 127 | // logger.debug("从JAR包中读取类: {}", jarPath); 128 | // } 129 | 130 | JarInputStream jarIn = new JarInputStream(new FileInputStream(jarPath)); 131 | JarEntry entry = jarIn.getNextJarEntry(); 132 | 133 | List nameList = new ArrayList<>(); 134 | while (null != entry) { 135 | String name = entry.getName(); 136 | if (name.startsWith(splashedPackageName) && isClassFile(name)) { 137 | nameList.add(name); 138 | } 139 | 140 | entry = jarIn.getNextJarEntry(); 141 | } 142 | jarIn.closeEntry(); 143 | jarIn.close(); 144 | return nameList; 145 | } 146 | 147 | private List readFromDirectory(String path) { 148 | File file = new File(path); 149 | String[] names = file.list(); 150 | 151 | if (null == names) { 152 | return null; 153 | } 154 | 155 | return Arrays.asList(names); 156 | } 157 | 158 | private boolean isClassFile(String name) { 159 | return name.endsWith(".class"); 160 | } 161 | 162 | private boolean isJarFile(String name) { 163 | return name.endsWith(".jar"); 164 | } 165 | 166 | /** 167 | * For test purpose. 168 | */ 169 | // public static void main(String[] args) throws Exception { 170 | // ClasspathPackageScanner scan = new ClasspathPackageScanner("com.huxuemin.xblog.domain"); 171 | // scan.getFullyQualifiedClassNameList(); 172 | // } 173 | 174 | } 175 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/tools/CustomDateSerializer.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.tools; 2 | 3 | import java.io.IOException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | 7 | import com.fasterxml.jackson.core.JsonGenerator; 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.databind.JsonSerializer; 10 | import com.fasterxml.jackson.databind.SerializerProvider; 11 | 12 | public class CustomDateSerializer extends JsonSerializer { 13 | 14 | @Override 15 | public void serialize(Date value, JsonGenerator jsonGenerator, SerializerProvider provider) 16 | throws IOException, JsonProcessingException { 17 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 18 | jsonGenerator.writeString(sdf.format(value)); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/tools/HTMLEscape.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.tools; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | import com.huxuemin.xblog.infrastructure.RegexConstant; 6 | 7 | public class HTMLEscape { 8 | public static String escape(String str){ 9 | if(str != null){ 10 | str = Pattern.compile(RegexConstant.HTMLLT).matcher(str).replaceAll("<"); 11 | return Pattern.compile(RegexConstant.HTMLGT).matcher(str).replaceAll(">"); 12 | }else{ 13 | return str; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/tools/IDCreateFactory.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.tools; 2 | 3 | public class IDCreateFactory { 4 | private final static int prime = 8; 5 | static int loopNum = 1; 6 | 7 | public static synchronized long getId(){ 8 | long result = System.currentTimeMillis(); 9 | loopNum = loopNum%prime; 10 | result = result * prime + (loopNum ++); 11 | return result; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/tools/JSONTools.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.tools; 2 | 3 | import java.util.List; 4 | 5 | import com.google.gson.Gson; 6 | import com.google.gson.GsonBuilder; 7 | import com.huxuemin.xblog.infrastructure.ErrorMessage; 8 | 9 | public class JSONTools { 10 | 11 | public static String JSONMsg(int statusValue,String msg){ 12 | ErrorMessage obj = new ErrorMessage(statusValue, msg); 13 | Gson gson = new GsonBuilder().create(); 14 | return gson.toJson(obj); 15 | } 16 | 17 | public static String ObjectToJSON(Object obj){ 18 | Gson gson = new GsonBuilder().create(); 19 | return gson.toJson(obj); 20 | } 21 | 22 | public static String ListToJSON(List objs){ 23 | Gson gson = new GsonBuilder().create(); 24 | return gson.toJson(objs); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/tools/MD5Tools.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/java/com/huxuemin/xblog/infrastructure/tools/MD5Tools.java -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/tools/StringUtil.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.infrastructure.tools; 2 | 3 | import java.net.URL; 4 | 5 | public class StringUtil { 6 | private StringUtil() { 7 | 8 | } 9 | 10 | /** 11 | * "file:/home/whf/cn/fh" -> "/home/whf/cn/fh" 12 | * "jar:file:/home/whf/foo.jar!cn/fh" -> "/home/whf/foo.jar" 13 | */ 14 | public static String getRootPath(URL url) { 15 | String fileUrl = url.getFile(); 16 | int pos = fileUrl.indexOf('!'); 17 | 18 | // System.out.println("fileUrl:" + fileUrl); 19 | if (-1 == pos) { 20 | return fileUrl; 21 | } 22 | return fileUrl.substring(5, pos); 23 | } 24 | 25 | /** 26 | * "cn.fh.lightning" -> "cn/fh/lightning" 27 | * 28 | * @param name 29 | * @return 30 | */ 31 | public static String dotToSplash(String name) { 32 | return name.replaceAll("\\.", "/"); 33 | } 34 | 35 | /** 36 | * "Apple.class" -> "Apple" 37 | */ 38 | public static String trimExtension(String name) { 39 | int pos = name.indexOf('.'); 40 | if (-1 != pos) { 41 | return name.substring(0, pos); 42 | } 43 | 44 | return name; 45 | } 46 | 47 | /** 48 | * /application/home -> /home 49 | * 50 | * @param uri 51 | * @return 52 | */ 53 | public static String trimURI(String uri) { 54 | String trimmed = uri.substring(1); 55 | int splashIndex = trimmed.indexOf('/'); 56 | 57 | return trimmed.substring(splashIndex); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/infrastructure/tools/praseTools.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/java/com/huxuemin/xblog/infrastructure/tools/praseTools.java -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/ContextManager.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web; 2 | 3 | import javax.servlet.ServletContextEvent; 4 | 5 | import com.huxuemin.xblog.database.DBConnectionFactory; 6 | 7 | 8 | public class ContextManager implements javax.servlet.ServletContextListener{ 9 | 10 | @Override 11 | public void contextDestroyed(ServletContextEvent arg0) { 12 | // TODO Auto-generated method stub 13 | DBConnectionFactory.closeAllConnection(); 14 | } 15 | 16 | @Override 17 | public void contextInitialized(ServletContextEvent arg0) { 18 | // TODO Auto-generated method stub 19 | DBConnectionFactory.initDataBaseContext(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/ObjectHttpMessageConverter.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.springframework.http.HttpInputMessage; 8 | import org.springframework.http.HttpOutputMessage; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.http.converter.FormHttpMessageConverter; 11 | import org.springframework.http.converter.HttpMessageConverter; 12 | import org.springframework.http.converter.HttpMessageNotReadableException; 13 | import org.springframework.util.LinkedMultiValueMap; 14 | import org.springframework.util.MultiValueMap; 15 | 16 | import com.fasterxml.jackson.databind.ObjectMapper; 17 | 18 | /** 19 | *

20 | * Converts HTTP requests with bodies that are application/x-www-form-urlencoded 21 | * or multipart/form-data to an Object annotated with 22 | * {@link org.springframework.web.bind.annotation.RequestBody} in the the 23 | * handler method. 24 | * 25 | * @author Jesse Swidler 26 | */ 27 | public class ObjectHttpMessageConverter implements HttpMessageConverter { 28 | 29 | private final FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter(); 30 | private final ObjectMapper objectMapper = new ObjectMapper(); 31 | 32 | private static final LinkedMultiValueMap LINKED_MULTI_VALUE_MAP = new LinkedMultiValueMap<>(); 33 | private static final Class> LINKED_MULTI_VALUE_MAP_CLASS = (Class>) LINKED_MULTI_VALUE_MAP 34 | .getClass(); 35 | 36 | @Override 37 | public boolean canRead(Class clazz, MediaType mediaType) { 38 | return objectMapper.canSerialize(clazz) && formHttpMessageConverter.canRead(MultiValueMap.class, mediaType); 39 | } 40 | 41 | @Override 42 | public boolean canWrite(Class clazz, MediaType mediaType) { 43 | return false; 44 | } 45 | 46 | @Override 47 | public List getSupportedMediaTypes() { 48 | return formHttpMessageConverter.getSupportedMediaTypes(); 49 | } 50 | 51 | @Override 52 | public Object read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { 53 | Map input = formHttpMessageConverter.read(LINKED_MULTI_VALUE_MAP_CLASS, inputMessage) 54 | .toSingleValueMap(); 55 | return objectMapper.convertValue(input, clazz); 56 | } 57 | 58 | @Override 59 | public void write(Object o, MediaType contentType, HttpOutputMessage outputMessage) 60 | throws UnsupportedOperationException { 61 | throw new UnsupportedOperationException(""); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/WebConfig.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.ComponentScan; 5 | import org.springframework.context.annotation.ComponentScan.Filter; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.FilterType; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.web.servlet.ViewResolver; 10 | import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; 11 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 12 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 13 | import org.springframework.web.servlet.view.InternalResourceViewResolver; 14 | 15 | @Configuration 16 | @EnableWebMvc 17 | @ComponentScan(basePackages={"com.huxuemin.xblog.web"},excludeFilters = { 18 | @Filter(type = FilterType.ANNOTATION, value = Service.class) }) 19 | public class WebConfig extends WebMvcConfigurerAdapter{ 20 | 21 | @Bean 22 | public ViewResolver viewResolver(){ 23 | InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 24 | resolver.setPrefix("/WEB-INF/views/"); 25 | resolver.setSuffix(".html"); 26 | resolver.setExposeContextBeansAsAttributes(true); 27 | return resolver; 28 | } 29 | 30 | @Override 31 | public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configure){ 32 | configure.enable(); 33 | } 34 | 35 | // @Override 36 | // public void extendMessageConverters(List> converters) { 37 | // ObjectHttpMessageConverter objectHttpMessageConverter = new ObjectHttpMessageConverter(); 38 | // converters.add(objectHttpMessageConverter); 39 | // } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/restAPI/LoginAPI.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.restAPI; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpSession; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.ExceptionHandler; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import com.huxuemin.xblog.application.UserService; 16 | import com.huxuemin.xblog.domain.user.UserNotFoundException; 17 | import com.huxuemin.xblog.domain.user.UserVerifyFailedException; 18 | import com.huxuemin.xblog.infrastructure.ErrorMessage; 19 | import com.huxuemin.xblog.infrastructure.SessionConstant; 20 | import com.huxuemin.xblog.infrastructure.dtos.DisplayNameDTO; 21 | import com.huxuemin.xblog.infrastructure.dtos.UserInfoDTO; 22 | 23 | @RestController 24 | @RequestMapping(value = "/api/login") 25 | public class LoginAPI { 26 | 27 | @Autowired 28 | UserService userService; 29 | 30 | @RequestMapping(method = RequestMethod.POST, produces = { "application/json", "application/xml" }, consumes = { "application/json", "application/xml", 31 | "application/x-www-form-urlencoded" }) 32 | public ResponseEntity loginIn(@RequestParam(value = "loginId") String loginid, 33 | @RequestParam(value = "password") String password, HttpServletRequest hsRequest) { 34 | 35 | if (userService.verify(loginid, password)) { 36 | HttpSession session = hsRequest.getSession(); 37 | session.setAttribute(SessionConstant.USERNAME, loginid); 38 | session.setAttribute(SessionConstant.PASSWORD, password); 39 | UserInfoDTO info = userService.getUserInfo(loginid, password, loginid); 40 | return new ResponseEntity(info, HttpStatus.OK); 41 | } 42 | throw new UserVerifyFailedException(); 43 | } 44 | 45 | @RequestMapping(method = RequestMethod.GET, produces = { "application/json", "application/xml"}) 46 | public ResponseEntity loginInfo(HttpServletRequest request) { 47 | 48 | HttpSession session = request.getSession(); 49 | String username = (String) session.getAttribute(SessionConstant.USERNAME); 50 | if (username != null) { 51 | DisplayNameDTO dis = new DisplayNameDTO(username); 52 | dis.setDisplayName(userService.getUserDisplayName(username)); 53 | return new ResponseEntity(dis, HttpStatus.OK); 54 | } 55 | throw new UserNotFoundException(); 56 | } 57 | 58 | @RequestMapping(method = RequestMethod.DELETE, produces = { "application/json", "application/xml"}) 59 | public ResponseEntity LoginOut(HttpServletRequest request) { 60 | HttpSession session = request.getSession(); 61 | String username = (String) session.getAttribute(SessionConstant.USERNAME); 62 | 63 | if(username != null){ 64 | session.invalidate(); 65 | return new ResponseEntity("{\"message\":\"logout\"}",HttpStatus.OK); 66 | } 67 | throw new UserNotFoundException(); 68 | } 69 | 70 | @ExceptionHandler(UserNotFoundException.class) 71 | public ResponseEntity userNotFoundException(UserNotFoundException exception){ 72 | ErrorMessage errorMessage = new ErrorMessage(1,exception.getMessage()); 73 | return new ResponseEntity(errorMessage,HttpStatus.NOT_FOUND); 74 | } 75 | 76 | @ExceptionHandler(UserVerifyFailedException.class) 77 | public ResponseEntity userVerifyFailedException(UserVerifyFailedException exception){ 78 | ErrorMessage errorMessage = new ErrorMessage(1,exception.getMessage()); 79 | return new ResponseEntity(errorMessage,HttpStatus.FORBIDDEN); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/restAPI/UserAPI.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.restAPI; 2 | 3 | import java.net.URI; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpSession; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.http.HttpHeaders; 10 | import org.springframework.http.HttpStatus; 11 | import org.springframework.http.ResponseEntity; 12 | import org.springframework.web.bind.annotation.ExceptionHandler; 13 | import org.springframework.web.bind.annotation.ModelAttribute; 14 | import org.springframework.web.bind.annotation.PathVariable; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.RequestMethod; 17 | import org.springframework.web.bind.annotation.RequestParam; 18 | import org.springframework.web.bind.annotation.RestController; 19 | import org.springframework.web.util.UriComponentsBuilder; 20 | 21 | import com.huxuemin.xblog.application.UserService; 22 | import com.huxuemin.xblog.domain.user.UserNotFoundException; 23 | import com.huxuemin.xblog.domain.user.UserVerifyFailedException; 24 | import com.huxuemin.xblog.infrastructure.AuthConstant; 25 | import com.huxuemin.xblog.infrastructure.AuthException; 26 | import com.huxuemin.xblog.infrastructure.ErrorMessage; 27 | import com.huxuemin.xblog.infrastructure.SessionConstant; 28 | import com.huxuemin.xblog.infrastructure.SuccessMessage; 29 | import com.huxuemin.xblog.infrastructure.dtos.UserInfoDTO; 30 | 31 | @RestController 32 | @RequestMapping(value = "/api/user") 33 | public class UserAPI { 34 | 35 | @Autowired 36 | UserService userService; 37 | 38 | @RequestMapping(value = "/{username}", method = RequestMethod.GET, produces = { "application/json", 39 | "application/xml" }) 40 | public ResponseEntity userInfo(@PathVariable(value = "username") String usernameforinfo, 41 | HttpServletRequest request) { 42 | HttpSession session = request.getSession(); 43 | String username = (String) session.getAttribute(SessionConstant.USERNAME); 44 | String password = (String) session.getAttribute(SessionConstant.PASSWORD); 45 | UserInfoDTO dto = userService.getUserInfo(username, password, usernameforinfo); 46 | return new ResponseEntity(dto, HttpStatus.OK); 47 | } 48 | 49 | @RequestMapping(method = RequestMethod.POST, consumes = { "application/json", "application/xml", 50 | "application/x-www-form-urlencoded" }, produces = { "application/json", "application/xml" }) 51 | public ResponseEntity register(@RequestParam(value = "user_login") String username, 52 | @RequestParam(value = "user_password") String password, UriComponentsBuilder ucb, 53 | HttpServletRequest request) { 54 | UserInfoDTO userInfo = userService.register(username, password); 55 | HttpHeaders header = new HttpHeaders(); 56 | URI uri = ucb.path("/api/user/").path(username).build().toUri(); 57 | header.setLocation(uri); 58 | return new ResponseEntity(userInfo, header, HttpStatus.ACCEPTED); 59 | } 60 | 61 | @RequestMapping(value = "/{username}", method = RequestMethod.PUT, consumes = { "application/json", 62 | "application/xml", 63 | "application/x-www-form-urlencoded" }, produces = { "application/json", "application/xml" }) 64 | public ResponseEntity edit(@PathVariable(value = "username") String username, 65 | @ModelAttribute UserInfoDTO userInfo, HttpServletRequest request) { 66 | HttpSession session = request.getSession(); 67 | String loginId = (String) session.getAttribute(SessionConstant.USERNAME); 68 | String password = (String) session.getAttribute(SessionConstant.PASSWORD); 69 | 70 | // System.out.println("logindId:" + loginId); 71 | // System.out.println("userInfo.getUserName():" + 72 | // userInfo.getUserName()); 73 | 74 | if (!userInfo.getUserName().equals(username)) { 75 | throw new UserNotFoundException(); 76 | } 77 | 78 | userService.modifyUserInfo(loginId, password, userInfo); 79 | return new ResponseEntity(userInfo, HttpStatus.ACCEPTED); 80 | } 81 | 82 | @RequestMapping(value = "/{username}/canedit", method = RequestMethod.GET, produces = { "application/json" }) 83 | public ResponseEntity canEdit(@PathVariable(value = "username") String username, 84 | HttpServletRequest request) { 85 | HttpSession session = request.getSession(); 86 | String loginId = (String) session.getAttribute(SessionConstant.USERNAME); 87 | String password = (String) session.getAttribute(SessionConstant.PASSWORD); 88 | 89 | if (userService.hasEditUserInfoAuth(loginId, password, username)) { 90 | return new ResponseEntity(new SuccessMessage(200, "Can edit!"), HttpStatus.OK); 91 | } 92 | throw new AuthException(AuthConstant.USER_MANAGER); 93 | } 94 | 95 | @RequestMapping(value = "/{username}/password", method = RequestMethod.PUT, produces = { "application/json" }) 96 | public ResponseEntity password(@PathVariable(value = "username") String username, 97 | @RequestParam(value = "old_password") String oldPassword, 98 | @RequestParam(value = "new_password") String newPassword, HttpServletRequest request) { 99 | if(userService.changePassword(username,oldPassword,newPassword)){ 100 | return new ResponseEntity(new SuccessMessage(200, "The password is changed!"), HttpStatus.OK); 101 | } 102 | throw new AuthException(AuthConstant.USER_MANAGER); 103 | } 104 | 105 | @ExceptionHandler(UserNotFoundException.class) 106 | public ResponseEntity userNotFoundException(UserNotFoundException exception) { 107 | ErrorMessage errorMessage = new ErrorMessage(1, exception.getMessage()); 108 | return new ResponseEntity(errorMessage, HttpStatus.NOT_FOUND); 109 | } 110 | 111 | @ExceptionHandler(AuthException.class) 112 | public ResponseEntity authException(AuthException authException) { 113 | ErrorMessage error = new ErrorMessage(1, authException.getMessage()); 114 | return new ResponseEntity(error, HttpStatus.FORBIDDEN); 115 | } 116 | 117 | @ExceptionHandler(UserVerifyFailedException.class) 118 | public ResponseEntity userVerifyFailedException(UserVerifyFailedException exception) { 119 | ErrorMessage error = new ErrorMessage(1, exception.getMessage()); 120 | return new ResponseEntity(error, HttpStatus.FORBIDDEN); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/viewController/ApiController.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.viewController; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | @Controller 8 | @RequestMapping(value="/api") 9 | public class ApiController { 10 | 11 | @RequestMapping(method=RequestMethod.GET) 12 | public String api(){ 13 | return "api"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/viewController/ArticleController.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.viewController; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | import javax.servlet.http.HttpSession; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | 12 | import com.huxuemin.xblog.application.UserService; 13 | import com.huxuemin.xblog.infrastructure.AuthException; 14 | import com.huxuemin.xblog.infrastructure.SessionConstant; 15 | 16 | @Controller 17 | @RequestMapping(value = "/article") 18 | public class ArticleController { 19 | 20 | @Autowired 21 | private UserService userService; 22 | 23 | @RequestMapping(value = "/{articleId}") 24 | public String article(@PathVariable long articleId) { 25 | return "article"; 26 | } 27 | 28 | @RequestMapping(value = "/publish/") 29 | public String create(HttpServletRequest request, HttpServletResponse response) { 30 | HttpSession session = request.getSession(); 31 | String userName = (String) session.getAttribute(SessionConstant.USERNAME); 32 | String password = (String) session.getAttribute(SessionConstant.PASSWORD); 33 | try { 34 | if (userService.manage(userName, password)) { 35 | response.addHeader("Cache-Control", "no-store"); 36 | return "publish"; 37 | } 38 | } catch (AuthException e) { 39 | // e.printStackTrace(); 40 | } 41 | return "redirect:/index"; 42 | } 43 | 44 | @RequestMapping(value = "/publish/{articleId}") 45 | public String edit(@PathVariable long articleId, HttpServletRequest request, HttpServletResponse response) { 46 | HttpSession session = request.getSession(); 47 | String userName = (String) session.getAttribute(SessionConstant.USERNAME); 48 | String password = (String) session.getAttribute(SessionConstant.PASSWORD); 49 | try { 50 | if (userService.manage(userName, password)) { 51 | response.addHeader("Cache-Control", "no-store"); 52 | return "publish"; 53 | } 54 | } catch (AuthException e) { 55 | // e.printStackTrace(); 56 | } 57 | return "redirect:/article/" + articleId; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/viewController/HomeController.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.viewController; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | @Controller 8 | @RequestMapping(value={"/","/home","/homepage","/index"}) 9 | public class HomeController { 10 | 11 | @RequestMapping(method=RequestMethod.GET) 12 | public String home(){ 13 | return "index"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/viewController/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.viewController; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | @Controller 8 | @RequestMapping(value="/login") 9 | public class LoginController { 10 | 11 | @RequestMapping(method=RequestMethod.GET) 12 | public String login(){ 13 | return "login"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/viewController/ManagePageController.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.viewController; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | import javax.servlet.http.HttpSession; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | 12 | import com.huxuemin.xblog.application.UserService; 13 | import com.huxuemin.xblog.infrastructure.AuthException; 14 | import com.huxuemin.xblog.infrastructure.SessionConstant; 15 | 16 | @Controller 17 | @RequestMapping(value = {"/manage","/admin"}) 18 | public class ManagePageController { 19 | 20 | @Autowired 21 | private UserService userService; 22 | 23 | @RequestMapping(method = RequestMethod.GET) 24 | public String register(HttpServletRequest request,HttpServletResponse response) { 25 | HttpSession session = request.getSession(); 26 | String userName = (String) session.getAttribute(SessionConstant.USERNAME); 27 | String password = (String) session.getAttribute(SessionConstant.PASSWORD); 28 | try { 29 | if (userService.manage(userName, password)) { 30 | response.addHeader("Cache-Control", "no-store"); 31 | return "manage"; 32 | } 33 | } catch (AuthException e) { 34 | //e.printStackTrace(); 35 | } 36 | return "redirect:/index"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/viewController/RegisterController.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.viewController; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | @Controller 8 | @RequestMapping(value="/register") 9 | public class RegisterController { 10 | 11 | @RequestMapping(method=RequestMethod.GET) 12 | public String register(){ 13 | return "register"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/huxuemin/xblog/web/viewController/UserController.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.web.viewController; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | import javax.servlet.http.HttpSession; 6 | 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | 12 | import com.huxuemin.xblog.infrastructure.SessionConstant; 13 | 14 | @Controller 15 | @RequestMapping(value = "/user") 16 | public class UserController { 17 | 18 | @RequestMapping(value = "/{userName}", method = RequestMethod.GET) 19 | public String user(@PathVariable String userName) { 20 | return "userinfo"; 21 | } 22 | 23 | @RequestMapping(value = "/{userName}/password", method = RequestMethod.GET) 24 | public String password(@PathVariable String userName, HttpServletRequest request, HttpServletResponse response) { 25 | 26 | HttpSession session = request.getSession(); 27 | String loginId = (String) session.getAttribute(SessionConstant.USERNAME); 28 | if (loginId != null && loginId.equals(userName)) { 29 | response.addHeader("Cache-Control", "no-store"); 30 | return "password"; 31 | } 32 | return "404"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/webapp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/.DS_Store -------------------------------------------------------------------------------- /src/main/webapp/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/webapp/.idea/webapp.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/WEB-INF/.DS_Store -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 心有猛虎,细嗅蔷薇 14 | 15 | 16 |
17 |
18 | 35 |
36 |
37 | 38 |
39 | 40 |
41 |

心有猛虎,细嗅蔷薇

42 |

写点代码虚度光阴.

43 |
44 |
45 |
46 |
47 |

404 Error   :所查找的页面不存在,可能已被删除或您输错了网址!

48 |

49 | 52 |
53 |
54 |
55 | 56 |
57 | 58 | 65 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/api.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 心有猛虎,细嗅蔷薇 14 | 15 | 16 |
17 |
18 | 35 |
36 |
37 | 38 |
39 | 40 |
41 |

心有猛虎,细嗅蔷薇

42 |

写点代码虚度光阴.

43 |
44 | 45 |
46 |
47 |
48 |

1、服务器接受数据。支持此xml、json、x-www-form-urlencoded三种格式.

49 |

2、返回数据支持xml、json格式。

50 |

例: http://www.huxuemin.com/api/articles.xml 51 | 、http://www.huxuemin.com/api/articles.json 52 |

53 |
54 |
55 | 66 |
67 |
68 | 69 | 1、获取文章目录: /api/article。请求类型:GET。 70 | 71 |

72 | 2、文章内容:/api/article/{articleId}。请求类型:GET。
73 | 例:/api/article/11804505069905。 74 |

75 |

76 | 3、删除文章:/api/article/{articleId}。请求类型:DELETE。
77 |

78 |

79 | 4、关闭文章评论:/api/article/{articleId}/discuss/close。请求类型:PUT。 80 |

81 |

82 | 5、打开文章评论:/api/article/{articleId}/discuss/open。请求类型:PUT。 83 |

84 |

85 | 6、查询文章是否可以评论:/api/article/{articleId}/discuss/canreply。请求类型:GET。 86 |

87 |

88 | 7、发布新文章:/api/article。请求类型:POST。 89 |

90 |

91 | 8、修改文章:/api/article/{articleId}。请求类型:PUT。 92 |

93 |
94 |
95 |

96 | 1、文章所有评论:/api/article/{articleId}/discuss。请求类型:GET。 97 |

98 |

99 | 2、评论页面数:/api/article/{articleId}/discuss/page,每页10条评论。请求类型:GET。 100 |

101 |

102 | 3、获取指定页评论:/api/article/{articleId}/discuss/page/{number},请求类型:GET。 103 |

104 |

105 | 4、回复文章:/api/article/{articleId}/discuss,请求类型:POST。 106 |

107 |

108 | 5、回复文章评论:/api/article/{articleId}/discuss/{discussId},请求类型:POST。 109 |

110 |
111 |
112 |

113 | 1、用户登录信息:/api/login,请求类型:GET。 114 |

115 |

116 | 2、用户登录:/api/login,请求类型:POST。 117 |

118 |

119 | 3、用户退出:/api/login,请求类型:DELETE。 120 |

121 |

122 | 4、是否具有修改该用户资料权限:/api/user/{username}/canedit,请求类型:GET。 123 |

124 |

125 | 5、获取用户资料:/api/user/{username},请求类型:GET。 126 |

127 |

128 | 6、修改该用户资料:/api/user/{username},请求类型:PUT。 129 |

130 |

131 | 7、用户注册:/api/user,请求类型:POST。 132 |

133 |
134 |
135 |
136 |
137 |
138 |
139 | 140 |
141 | 142 |
143 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/article/templet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 心有猛虎,细嗅蔷薇 14 | 15 | 16 |
17 |
18 |
19 |

20 | 心有猛虎,细嗅蔷薇 21 |

22 | 33 |

34 | 第一篇文章 35 |

36 | 37 |

38 | 本可视化布局程序在HTML5浏览器上运行更加完美, 能实现自动本地化保存, 即使关闭了网页, 下一次打开仍然能恢复上一次的操作. 39 |

40 | 41 | 评论列表: 42 |
    43 |
  • 44 | 胡学敏 1#:文章还不错 45 |
  • 46 |
  • 47 | 周杰伦 2#:文章还不错 48 |
  • 49 |
50 |
51 |
52 | 53 |
54 | 55 |
56 | 57 |
58 |
59 |
60 | 61 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 心有猛虎,细嗅蔷薇 14 | 15 | 16 |
17 |
18 | 35 |
36 |
37 | 38 |
39 | 40 |
41 |

心有猛虎,细嗅蔷薇

42 |

写点代码虚度光阴.

43 |
44 |
45 |
46 |
47 |

Blog

48 |
49 |

50 | 51 | 52 |
53 | 54 | 55 | 56 |
57 | 76 |
77 | 78 | 79 | 86 | 112 | 113 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 心有猛虎,细嗅蔷薇 14 | 15 | 16 |
17 |
18 | 35 |
36 |
37 | 38 |
39 | 40 |
41 |

心有猛虎,细嗅蔷薇

42 |

写点代码虚度光阴.

43 |
44 | 45 |
46 |
47 |
48 |
49 |
50 | 94 | 99 |
100 |
101 |
102 | 103 |
104 | 105 |
106 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/manage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 心有猛虎,细嗅蔷薇 15 | 16 | 17 |
18 |
19 | 36 |
37 |
38 | 39 |
40 | 41 |
42 |

心有猛虎,细嗅蔷薇

43 |

写点代码虚度光阴.

44 |
45 | 46 |
47 |
48 |
49 |
50 |
51 | 62 |
63 |
64 | 65 |
66 |
67 | 68 |
69 |
70 | 71 |
72 |
73 |
74 |
75 | 76 |
77 | 78 |
79 | 80 |
81 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | log4jConfigLocation 8 | classpath:log4j.xml 9 | 10 | 11 | 12 | 13 | rootLevel 14 | DEBUG 15 | 16 | 17 | 18 | loggingLevel 19 | INFO 20 | 21 | 22 | 23 | org.springframework.web.util.Log4jConfigListener 24 | 25 | 26 | com.huxuemin.xblog.web.ContextManager 27 | 28 | 29 | 404 30 | /WEB-INF/views/404.html 31 | 32 | 33 | 400 34 | /WEB-INF/views/404.html 35 | 36 | 37 | 500 38 | /WEB-INF/views/404.html 39 | 40 | 41 | 403 42 | /WEB-INF/views/404.html 43 | 44 | 45 | 405 46 | /WEB-INF/views/404.html 47 | 48 | 51 | 52 | -------------------------------------------------------------------------------- /src/main/webapp/css/xblog.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Globals 3 | */ 4 | body { 5 | font-family: Georgia, "Times New Roman", Times, serif; 6 | color: #555; 7 | margin: 0; 8 | padding: 0; 9 | } 10 | 11 | h1, .h1, 12 | h2, .h2, 13 | h3, .h3, 14 | h4, .h4, 15 | h5, .h5, 16 | h6, .h6 { 17 | margin-top: 0; 18 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 19 | font-weight: normal; 20 | color: #333; 21 | } 22 | 23 | /* 24 | * Override Bootstrap's default container. 25 | */ 26 | 27 | @media (min-width: 1200px) { 28 | .container { 29 | width: 970px; 30 | } 31 | } 32 | 33 | /* 34 | * Masthead for nav 35 | */ 36 | 37 | .blog-masthead { 38 | background-color: #428bca; 39 | -webkit-box-shadow: inset 0 -2px 5px rgba(0, 0, 0, .1); 40 | box-shadow: inset 0 -2px 5px rgba(0, 0, 0, .1); 41 | } 42 | 43 | /* Nav links */ 44 | .blog-nav-item { 45 | position: relative; 46 | display: inline-block; 47 | padding: 10px; 48 | font-weight: 500; 49 | color: #cdddeb; 50 | } 51 | 52 | .blog-nav-item:hover, 53 | .blog-nav-item:focus { 54 | color: #fff; 55 | text-decoration: none; 56 | } 57 | 58 | .blog-nav-login-status { 59 | float: right; 60 | } 61 | 62 | .show { 63 | display: inline; 64 | } 65 | 66 | .hide { 67 | display: none; 68 | } 69 | 70 | .welcome-title { 71 | color: #cdddeb; 72 | } 73 | 74 | /* Active state gets a caret at the bottom */ 75 | .blog-nav .active { 76 | color: #fff; 77 | } 78 | 79 | .blog-nav .active:after { 80 | position: absolute; 81 | bottom: 0; 82 | left: 50%; 83 | width: 0; 84 | height: 0; 85 | margin-left: -5px; 86 | vertical-align: middle; 87 | content: " "; 88 | border-right: 5px solid transparent; 89 | border-bottom: 5px solid; 90 | border-left: 5px solid transparent; 91 | } 92 | 93 | /* 94 | * Blog name and description 95 | */ 96 | 97 | .blog-header { 98 | padding-top: 20px; 99 | padding-bottom: 20px; 100 | } 101 | 102 | .blog-title { 103 | margin-top: 30px; 104 | margin-bottom: 0; 105 | font-size: 45px; 106 | font-weight: normal; 107 | } 108 | 109 | .blog-description { 110 | font-size: 20px; 111 | color: #999; 112 | } 113 | 114 | /* 115 | * Main column and sidebar layout 116 | */ 117 | 118 | .blog-main { 119 | font-size: 18px; 120 | line-height: 1.5; 121 | } 122 | 123 | .blog-table { 124 | -webkit-border-radius: 4px; 125 | -moz-border-radius: 4px; 126 | border-radius: 4px; 127 | } 128 | 129 | /* Sidebar modules for boxing content */ 130 | .sidebar-module { 131 | padding: 15px; 132 | margin: 0 -15px 15px; 133 | } 134 | 135 | .sidebar-module-inset { 136 | padding: 15px; 137 | background-color: #f5f5f5; 138 | border-radius: 4px; 139 | } 140 | 141 | .sidebar-module-inset p:last-child, 142 | .sidebar-module-inset ul:last-child, 143 | .sidebar-module-inset ol:last-child { 144 | margin-bottom: 0; 145 | } 146 | 147 | /* Pagination */ 148 | .pager { 149 | margin-bottom: 60px; 150 | text-align: left; 151 | } 152 | 153 | .pager > li > a { 154 | width: 140px; 155 | padding: 10px 20px; 156 | text-align: center; 157 | border-radius: 30px; 158 | } 159 | 160 | /* 161 | * Blog posts 162 | */ 163 | 164 | .blog-post { 165 | margin-bottom: 60px; 166 | } 167 | 168 | .blog-post-title { 169 | margin-bottom: 5px; 170 | font-size: 40px; 171 | } 172 | 173 | .blog-post-meta { 174 | margin-bottom: 20px; 175 | color: #999; 176 | } 177 | 178 | .blog-discuss { 179 | margin-bottom: 60px; 180 | } 181 | 182 | .blog-discuss-comments { 183 | display: block; 184 | width: 80%; 185 | height: 120px; 186 | margin-bottom: 20px; 187 | } 188 | 189 | .clsError { 190 | font-size: 13px; 191 | border: solid 1px #cc3300; 192 | padding: 2px; 193 | display: none; 194 | margin-bottom: 5px; 195 | background-color: #ffe0a3; 196 | } 197 | 198 | .blog-login-form{ 199 | margin-top: 20px; 200 | margin-bottom: 200px; 201 | } 202 | .blog-login-form table { 203 | margin-top: 1em; 204 | padding: 1em; 205 | margin-left: auto; 206 | margin-right: auto; 207 | border: 2px solid #F0F0F0; 208 | background-color: #F5F5F5; 209 | font-size: 14px; 210 | } 211 | 212 | .blog-login-form table td { 213 | padding: 15px; 214 | } 215 | 216 | .blog-login-form label { 217 | font-weight: bold; 218 | } 219 | 220 | .blog-login-form input#loginid, #login-form input#password { 221 | width: 300px; 222 | } 223 | 224 | #main.nosidebar #content { 225 | width: auto; 226 | border-right: 0; 227 | } 228 | 229 | .blog-register-box { 230 | padding: 6px; 231 | margin-bottom: 10px; 232 | background-color: #f6f6f6; 233 | color: #505050; 234 | line-height: 1.5em; 235 | border: 1px solid #e4e4e4; 236 | word-wrap: break-word; 237 | } 238 | 239 | /***** blog-register-tabular forms ******/ 240 | .blog-register-tabular{ 241 | font-size: 14px; 242 | } 243 | 244 | .blog-register-tabular input, .blog-register-tabular select { 245 | max-width: 95% 246 | } 247 | .blog-register-tabular>div{ 248 | margin-top:12px; 249 | } 250 | .blog-register-tabular textarea { 251 | width: 95%; 252 | resize: vertical; 253 | } 254 | 255 | .blog-register-tabular label { 256 | font-weight: bold; 257 | float: left; 258 | text-align: right; 259 | /* width of left column */ 260 | margin-left: -60px; 261 | /* width of labels. Should be smaller than left column to create some right margin */ 262 | width: 175px; 263 | } 264 | 265 | .blog-register-content{ 266 | margin-top:20px; 267 | } 268 | 269 | .line { 270 | height: 1px; 271 | background: gainsboro; 272 | } 273 | 274 | #editor { 275 | resize:vertical; 276 | overflow:auto; 277 | border:1px solid silver; 278 | border-radius:5px; 279 | min-height:100px; 280 | height:500px; 281 | box-shadow: inset 0 0 10px silver; 282 | padding:1em; 283 | } 284 | 285 | .blog-discuss-area{ 286 | margin-top:20px; 287 | } 288 | /* 289 | * Footer 290 | */ 291 | 292 | .blog-footer { 293 | padding: 40px 0; 294 | color: #999; 295 | text-align: center; 296 | background-color: #f9f9f9; 297 | border-top: 1px solid #e5e5e5; 298 | } 299 | 300 | .blog-footer p:last-child { 301 | margin-bottom: 0; 302 | } 303 | .error-div{ 304 | position:relative; 305 | z-index:2; 306 | width:540px; 307 | height:0; 308 | margin:60px; 309 | padding:230px 0 0; 310 | overflow:hidden; 311 | xxxxborder:1px solid; 312 | background-image: url(/images/Main.jpg); 313 | background-repeat: no-repeat; 314 | } 315 | 316 | 317 | -------------------------------------------------------------------------------- /src/main/webapp/font/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/font/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/main/webapp/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/main/webapp/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/main/webapp/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/main/webapp/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/main/webapp/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/glyphicons-halflings.png -------------------------------------------------------------------------------- /src/main/webapp/images/Favicon_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/images/Favicon_big.png -------------------------------------------------------------------------------- /src/main/webapp/images/Home.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/images/Home.ico -------------------------------------------------------------------------------- /src/main/webapp/images/Main.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/main/webapp/images/Main.jpg -------------------------------------------------------------------------------- /src/main/webapp/js/default-main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by huxuemin on 2016-5-18. 3 | */ 4 | (function($){ 5 | var curDiscussPage; 6 | $.simpleBlog = function(){ 7 | }; 8 | 9 | $.simpleBlog.asynSubmit = function(el, options) { 10 | var base = this; 11 | base.$el = $(el); 12 | base.el = el; 13 | base.$el.data("asynSubmit", base); 14 | base.init = function() { 15 | base.options = $.extend({}, $.simpleBlog.asynSubmit.defaultOptions, options); 16 | if (base.options.submitElement !== false) { 17 | var $submitElement = base.options.submitElement; 18 | } else { 19 | var $submitElement = base.$el.find(":input:submit"); 20 | } 21 | $submitElement.bind(base.options.submitEvent,function() { 22 | $(this).attr("disabled",true); 23 | if(base.options.beforeSubmit()) { 24 | $.ajax({ 25 | url: base.$el.attr("action"), 26 | type: base.$el.attr("method"), 27 | dataType:'json', 28 | data: base.$el.serializeArray(), 29 | success: base.options.successSubmit, 30 | error: base.options.errorSubmit, 31 | complete: function(XMLHttpRequest, textStatus){ 32 | $submitElement.attr("disabled",false); 33 | base.options.completeSubmit(XMLHttpRequest, textStatus); 34 | } 35 | }); 36 | }else{ 37 | $(this).attr("disabled",false); 38 | } 39 | return false; 40 | }); 41 | }; 42 | base.init(); 43 | }; 44 | 45 | $.simpleBlog.asynSubmit.defaultOptions = { 46 | submitElement:false, 47 | submitEvent:"click", 48 | beforeSubmit:function(){return true}, 49 | successSubmit:function(data){}, 50 | errorSubmit:function(XMLHttpRequest, textStatus, errorThrown){}, 51 | completeSubmit:function(XMLHttpRequest, textStatus){} 52 | }; 53 | 54 | $.simpleBlog.jump = function (second,urlstr) { 55 | window.setTimeout(function(){ 56 | second--; 57 | if(second > 0) { 58 | $.simpleBlog.jump(second,urlstr); 59 | } else { 60 | location.href=urlstr; 61 | } 62 | }, 1000); 63 | }; 64 | 65 | $.simpleBlog.getArticleId = function (){ 66 | var reg = new RegExp(".*/article/(\\\d+)(?=(?:/|\\\?|\\\.|$)).*",""); 67 | var r = window.location.pathname.match(reg); 68 | if(r!=null){ 69 | return r[1]; 70 | } else{ 71 | return null; 72 | } 73 | }; 74 | 75 | $.simpleBlog.getPublishId = function (){ 76 | var reg = new RegExp(".*/publish/(\\\d+)(?=(?:/|\\\?|\\\.|$)).*",""); 77 | var r = window.location.pathname.match(reg); 78 | if(r!=null){ 79 | return r[1]; 80 | } else{ 81 | return null; 82 | } 83 | }; 84 | 85 | $.simpleBlog.getUserName = function (){ 86 | var reg = new RegExp(".*/user/(\\\w+)(?=(?:/|\\\?|\\\.|$)).*",""); 87 | var r = window.location.pathname.match(reg); 88 | if(r!=null){ 89 | return r[1]; 90 | } else{ 91 | return null; 92 | } 93 | }; 94 | 95 | $.simpleBlog.refreshUserNameArea = function(){ 96 | $.ajax({ 97 | url: "/api/login", 98 | type: "GET", 99 | dataType: 'json', 100 | data: {}, 101 | success: function (data) { 102 | $("#login_register").removeClass("show").addClass("hide"); 103 | $("#logoutArea").removeClass("hide").addClass("show"); 104 | $("#userDisplayName").attr("href","/user/"+$.trim(data.userName)); 105 | $("#userDisplayName").text(data.displayName); 106 | }, 107 | error: function() { 108 | $("#logoutArea").removeClass("show").addClass("hide"); 109 | $("#login_register").removeClass("hide").addClass("show"); 110 | $("#userDisplayName").attr("href","#"); 111 | $("#userDisplayName").text(""); 112 | } 113 | }); 114 | // Command.interface?command=Logout 115 | $("#logout").click(function(){ 116 | $.ajax({ 117 | url: "/api/login", 118 | type: "DELETE", 119 | dataType: 'json', 120 | data: {}, 121 | success: function () { 122 | $("#logoutArea").removeClass("show").addClass("hide"); 123 | $("#login_register").removeClass("hide").addClass("show"); 124 | $("#userDisplayName").attr("href","#"); 125 | $("#userDisplayName").text(""); 126 | }, 127 | error: function() { 128 | } 129 | }); 130 | }); 131 | }; 132 | 133 | $.fn.asynSubmit = function(options) { 134 | return this.each(function(){ 135 | (new $.simpleBlog.asynSubmit(this, options)); 136 | }); 137 | }; 138 | 139 | Date.prototype.Format = function (fmt) { // author: meizz 140 | var o = { 141 | "M+": this.getMonth() + 1, // 月份 142 | "d+": this.getDate(), // 日 143 | "H+": this.getHours(), // 小时 144 | "m+": this.getMinutes(), // 分 145 | "s+": this.getSeconds(), // 秒 146 | "q+": Math.floor((this.getMonth() + 3) / 3), // 季度 147 | "S": this.getMilliseconds() // 毫秒 148 | }; 149 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 150 | for (var k in o) 151 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 152 | return fmt; 153 | } 154 | 155 | })(jQuery); 156 | -------------------------------------------------------------------------------- /src/main/webapp/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /src/test/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hu-xuemin/xBlog/585f0de5563b492b377f4cce6523699b9ef496eb/src/test/.DS_Store -------------------------------------------------------------------------------- /src/test/java/com/huxuemin/xblog/test/web/ArticleServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.huxuemin.xblog.test.web; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Rule; 6 | import org.junit.Test; 7 | import org.junit.contrib.java.lang.system.SystemOutRule; 8 | import org.junit.rules.ExpectedException; 9 | import org.junit.runner.RunWith; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.test.context.ContextConfiguration; 12 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 13 | 14 | import com.huxuemin.xblog.application.ArticleService; 15 | import com.huxuemin.xblog.config.RootConfig; 16 | import com.huxuemin.xblog.database.DBConnectionFactory; 17 | import com.huxuemin.xblog.domain.article.ArticleNotFoundException; 18 | 19 | @RunWith(SpringJUnit4ClassRunner.class) 20 | @ContextConfiguration(classes=RootConfig.class) 21 | public class ArticleServiceTest { 22 | 23 | @Rule 24 | public final SystemOutRule systemOutRule = new SystemOutRule().enableLog(); 25 | 26 | @Rule 27 | public ExpectedException expectedEx = ExpectedException.none(); 28 | 29 | @Autowired 30 | ArticleService articleService; 31 | 32 | @Before 33 | public void setUp() { 34 | DBConnectionFactory.initDataBaseContext(); 35 | } 36 | 37 | @After 38 | public void destory() { 39 | DBConnectionFactory.closeAllConnection(); 40 | } 41 | 42 | @Test 43 | public void number(){ 44 | expectedEx.expect(ArticleNotFoundException.class); 45 | expectedEx.expectMessage("Article not found!"); 46 | articleService.numberOfDiscuss(123); 47 | } 48 | } 49 | --------------------------------------------------------------------------------