reddit improvements

This commit is contained in:
DOHA 2015-05-09 22:30:57 +02:00
parent 57bfaaed1c
commit 60147a272f
24 changed files with 292 additions and 229 deletions

View File

@ -0,0 +1 @@
web: java $JAVA_OPTS -jar target/dependency/webapp-runner.jar --port $PORT target/*.war

View File

@ -106,6 +106,26 @@
<version>${httpcore.version}</version>
</dependency>
<!-- thymeleaf -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity3</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<!-- persistence -->
<dependency>
@ -140,6 +160,14 @@
<scope>runtime</scope>
</dependency>
<!-- h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.187</version>
</dependency>
<!-- web -->
<dependency>
@ -329,6 +357,29 @@
</configuration>
</plugin>
<!-- webapp runner -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>copy</goal></goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.github.jsimone</groupId>
<artifactId>webapp-runner</artifactId>
<version>7.0.57.2</version>
<destFileName>webapp-runner.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

View File

@ -34,7 +34,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.httpBasic().authenticationEntryPoint(oauth2AuthenticationEntryPoint())
.and()
.logout()
.deleteCookies("JSESSIONID","CustomRememberMe")
.deleteCookies("JSESSIONID")
.logoutUrl("/logout")
.logoutSuccessUrl("/");
// @formatter:on

View File

@ -13,7 +13,7 @@ public class ServletInitializer extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createServletApplicationContext() {
final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(PersistenceJPAConfig.class, WebConfig.class, SecurityConfig.class);
context.register(PersistenceJPAConfig.class, WebConfig.class, SecurityConfig.class, ThymeleafConfig.class);
return context;
}

View File

@ -13,7 +13,7 @@ public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
logger.info("==== Session is created ====");
event.getSession().setMaxInactiveInterval(30 * 60);
event.getSession().setMaxInactiveInterval(60 * 60);
event.getSession().setAttribute("PREDICTION_FEATURE", MyFeatures.PREDICTION_FEATURE);
}

View File

@ -0,0 +1,39 @@
package org.baeldung.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
@Configuration
public class ThymeleafConfig {
@Bean
public TemplateResolver templateResolver() {
final ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/jsp/");
templateResolver.setSuffix(".jsp");
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new SpringSecurityDialect());
return templateEngine;
}
@Bean
public ViewResolver viewResolver() {
final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setOrder(1);
return viewResolver;
}
}

View File

@ -5,7 +5,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.baeldung.persistence.service.RedditTokenService;
import javax.annotation.PostConstruct;
import org.apache.commons.lang.StringUtils;
import org.baeldung.persistence.dao.PostRepository;
import org.baeldung.reddit.classifier.RedditClassifier;
import org.baeldung.reddit.util.MyFeatures;
import org.baeldung.reddit.util.UserAgentInterceptor;
@ -115,6 +118,9 @@ public class WebConfig extends WebMvcConfigurerAdapter {
@Value("${clientSecret}")
private String clientSecret;
@Autowired
private PostRepository repo;
@Bean
public OAuth2ProtectedResourceDetails reddit() {
final AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
@ -132,16 +138,24 @@ public class WebConfig extends WebMvcConfigurerAdapter {
}
@Bean
public OAuth2RestTemplate redditRestTemplate(OAuth2ClientContext clientContext, RedditTokenService redditTokenService) {
public OAuth2RestTemplate redditRestTemplate(OAuth2ClientContext clientContext) {
final OAuth2RestTemplate template = new OAuth2RestTemplate(reddit(), clientContext);
final List<ClientHttpRequestInterceptor> list = new ArrayList<ClientHttpRequestInterceptor>();
list.add(new UserAgentInterceptor());
template.setInterceptors(list);
final AccessTokenProviderChain accessTokenProvider = new AccessTokenProviderChain(Arrays.<AccessTokenProvider> asList(new MyAuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(), new ResourceOwnerPasswordAccessTokenProvider(),
new ClientCredentialsAccessTokenProvider()));
accessTokenProvider.setClientTokenServices(redditTokenService);
template.setAccessTokenProvider(accessTokenProvider);
return template;
}
@PostConstruct
public void startupCheck() {
if (StringUtils.isBlank(accessTokenUri) || StringUtils.isBlank(userAuthorizationUri) || StringUtils.isBlank(clientID) || StringUtils.isBlank(clientSecret)) {
throw new RuntimeException("Incomplete reddit properties");
}
repo.findAll();
}
}
}

View File

@ -8,6 +8,4 @@ public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
User findByAccessToken(String token);
User findByRememberMeToken(String token);
}

View File

@ -26,8 +26,6 @@ public class User {
private boolean needCaptcha;
private String rememberMeToken;
public User() {
super();
}
@ -82,14 +80,6 @@ public class User {
//
public String getRememberMeToken() {
return rememberMeToken;
}
public void setRememberMeToken(String rememberMeToken) {
this.rememberMeToken = rememberMeToken;
}
@Override
public int hashCode() {
final int prime = 31;

View File

@ -1,55 +0,0 @@
package org.baeldung.persistence.service;
import org.baeldung.persistence.dao.UserRepository;
import org.baeldung.persistence.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.ClientTokenServices;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Component;
@Component
public class RedditTokenService implements ClientTokenServices {
@Autowired
private UserRepository userReopsitory;
private final Logger logger = LoggerFactory.getLogger(getClass());
public RedditTokenService() {
super();
}
@Override
public OAuth2AccessToken getAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication) {
logger.info("reddit ==== getAccessToken");
final User user = (User) authentication.getPrincipal();
final DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(user.getAccessToken());
token.setRefreshToken(new DefaultOAuth2RefreshToken((user.getRefreshToken())));
token.setExpiration(user.getTokenExpiration());
return token;
}
@Override
public void saveAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication, OAuth2AccessToken accessToken) {
logger.info("reddit ==== saveAccessToken");
final User user = (User) authentication.getPrincipal();
user.setAccessToken(accessToken.getValue());
if (accessToken.getRefreshToken() != null) {
user.setRefreshToken(accessToken.getRefreshToken().getValue());
}
user.setTokenExpiration(accessToken.getExpiration());
userReopsitory.save(user);
}
@Override
public void removeAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication) {
logger.info("reddit ==== removeAccessToken");
}
}

View File

@ -8,11 +8,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.RandomStringUtils;
import org.baeldung.persistence.dao.PostRepository;
import org.baeldung.persistence.dao.UserRepository;
import org.baeldung.persistence.model.Post;
@ -33,7 +28,6 @@ import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -50,7 +44,6 @@ public class RedditController {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
private final SimpleDateFormat dfHour = new SimpleDateFormat("HH");
public static final String REMEMBER_ME_COOKIE = "CustomRememberMe";
@Autowired
@Qualifier("redditRestTemplate")
@ -66,11 +59,9 @@ public class RedditController {
private RedditClassifier redditClassifier;
@RequestMapping("/login")
public final String redditLogin(@CookieValue(value = REMEMBER_ME_COOKIE, required = false) String rememberMe, HttpServletRequest request, HttpServletResponse response) {
if (!canAutoLogin(rememberMe)) {
public final String redditLogin() {
final JsonNode node = redditRestTemplate.getForObject("https://oauth.reddit.com/api/v1/me", JsonNode.class);
loadAuthentication(node.get("name").asText(), redditRestTemplate.getAccessToken(), response);
}
loadAuthentication(node.get("name").asText(), redditRestTemplate.getAccessToken());
return "redirect:home.html";
}
@ -229,14 +220,14 @@ public class RedditController {
return result;
} else {
if ((node.get("json").get("data") != null) && (node.get("json").get("data").get("url") != null)) {
return "Post submitted successfully <a href=\"" + node.get("json").get("data").get("url").asText() + "\"> check it out </a>";
return "Post submitted successfully " + node.get("json").get("data").get("url").asText();
} else {
return "Error Occurred";
}
}
}
private void loadAuthentication(final String name, final OAuth2AccessToken token, HttpServletResponse response) {
private void loadAuthentication(final String name, final OAuth2AccessToken token) {
User user = userReopsitory.findByUsername(name);
if (user == null) {
user = new User();
@ -254,35 +245,8 @@ public class RedditController {
user.setTokenExpiration(token.getExpiration());
userReopsitory.save(user);
generateRememberMeToken(user, response);
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, token.getValue(), Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
SecurityContextHolder.getContext().setAuthentication(auth);
}
private void generateRememberMeToken(User user, HttpServletResponse response) {
String rememberMe = RandomStringUtils.randomAlphanumeric(30);
while (userReopsitory.findByRememberMeToken(rememberMe) != null) {
rememberMe = RandomStringUtils.randomAlphanumeric(30);
}
user.setRememberMeToken(rememberMe);
userReopsitory.save(user);
final Cookie c = new Cookie(REMEMBER_ME_COOKIE, rememberMe);
c.setMaxAge(1209600);
response.addCookie(c);
}
private boolean canAutoLogin(String rememberMeToken) {
if (rememberMeToken != null) {
final User user = userReopsitory.findByRememberMeToken(rememberMeToken);
if (user != null) {
logger.info("Auto Login successfully");
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, user.getAccessToken(), Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
SecurityContextHolder.getContext().setAuthentication(auth);
return true;
}
}
return false;
}
}

View File

@ -1,10 +1,10 @@
################### DataSource Configuration ##########################
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/oauth_reddit?createDatabaseIfNotExist=true
jdbc.user=tutorialuser
jdbc.pass=tutorialmy5ql
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgres://fkqrbxdwqbrzhv:Y83Axvgz5iC_tyRZQxI0KEmUEG@ec2-107-20-222-114.compute-1.amazonaws.com:5432/dfmoej36meltnj
jdbc.user=fkqrbxdwqbrzhv
jdbc.pass=Y83Axvgz5iC_tyRZQxI0KEmUEG
################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=update

View File

@ -1,10 +1,10 @@
################### DataSource Configuration ##########################
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/oauth_reddit?createDatabaseIfNotExist=true
jdbc.user=tutorialuser
jdbc.pass=tutorialmy5ql
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:oauth_reddit;DB_CLOSE_DELAY=-1
jdbc.user=sa
jdbc.pass=
init-db=false
################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop
hibernate.hbm2ddl.auto=update

View File

@ -1,13 +1,12 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Schedule to Reddit</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="<c:url value="/resources/datetime-picker.css" />">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
<link rel="stylesheet" th:href="@{/resources/datetime-picker.css}" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="<c:url value="/resources/datetime-picker.js" />"></script>
<script src="<c:url value="/resources/validator.js" />"></script>
<script th:src="@{/resources/datetime-picker.js}"></script>
<script th:src="@{/resources/validator.js}"></script>
<style type="text/css">
.btn.disabled{
background-color: #ddd;
@ -21,42 +20,46 @@ border-color: #ddd;
</style>
</head>
<body>
<jsp:include page="header.jsp" />
<div th:include="header"/>
<div class="container">
<h1>Edit Scheduled Post</h1>
<form action="<c:url value="/updatePost/${post.getId()}" />" method="post" role="form" data-toggle="validator">
<form th:action="@{/updatePost/{id}(id=${post.getId()})}" method="post" role="form" data-toggle="validator">
<div class="row">
<input type="hidden" name="id" value="${post.getId()}"/>
<div class="form-group">
<label class="col-sm-3">Title</label>
<span class="col-sm-9"><input name="title" placeholder="title" class="form-control" value="${post.getTitle()}" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="title" placeholder="title" class="form-control" th:value="${post.getTitle()}" required="required" data-minlength="3"/></span>
</div>
<br><br>
<br/><br/>
<div class="form-group">
<label class="col-sm-3">Url</label>
<span class="col-sm-9"><input name="url" type="url" placeholder="url" class="form-control" value="${post.getUrl()}" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="url" type="url" placeholder="url" class="form-control" th:value="${post.getUrl()}" required="required" data-minlength="3"/></span>
</div>
<br><br>
<br/><br/>
<div class="form-group">
<label class="col-sm-3">Subreddit</label>
<span class="col-sm-9"><input name="sr" placeholder="Subreddit" class="form-control" value="${post.getSubreddit()}" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="sr" placeholder="Subreddit" class="form-control" th:value="${post.getSubreddit()}" required="required" data-minlength="3"/></span>
</div>
<br><br>
<br/><br/>
<div>
<label class="col-sm-3">Send replies to my inbox</label> <span class="col-sm-9"> <input type="checkbox" name="sendreplies" value="true" <c:if test="${post.isSendReplies()=='true'}"> checked </c:if> /></span>
<label class="col-sm-3">Send replies to my inbox</label>
<span class="col-sm-9">
<input th:if="${post.isSendReplies()=='true'}" type="checkbox" name="sendreplies" value="true" checked="checked"/>
<input th:if="${post.isSendReplies()=='false'}" type="checkbox" name="sendreplies" value="true" checked="checked"/>
</span>
</div>
<br><br>
<br/><br/>
<label class="col-sm-3">Submission Date</label>
<span class="col-sm-9"><input type="text" name="date" class="form-control" value="${dateValue}" readonly></span>
<span class="col-sm-9"><input type="text" name="date" class="form-control" th:value="${dateValue}" readonly="readonly"/></span>
<script type="text/javascript">
$(function(){
$('*[name=date]').appendDtpicker({"inline": true});
});
</script>
<br><br>
<br/><br/>
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>

View File

@ -1,24 +1,23 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="<c:url value="/home.html" />">Schedule to Reddit</a>
<a class="navbar-brand" th:href="@{/home.html}">Schedule to Reddit</a>
</div>
<p class="navbar-text navbar-right">Logged in as
<b><sec:authentication property="principal.username" /></b>&nbsp;&nbsp;&nbsp;
<a href="<c:url value="/logout" />">Logout</a>&nbsp;&nbsp;&nbsp;
<b><span sec:authentication="principal.username">Bob</span></b>&nbsp;&nbsp;&nbsp;
<a th:href="@{/logout}">Logout</a>&nbsp;&nbsp;&nbsp;
</p>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="<c:url value="/posts" />">My Scheduled Posts</a></li>
<li><a href="<c:url value="/post" />">Post to Reddit</a></li>
<li><a href="<c:url value="/postSchedule" />">Schedule Post to Reddit</a></li>
<li><a th:href="@{/posts}">My Scheduled Posts</a></li>
<li><a th:href="@{/post}">Post to Reddit</a></li>
<li><a th:href="@{/postSchedule}">Schedule Post to Reddit</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</div>

View File

@ -1,18 +1,16 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<html>
<head>
<title>Schedule to Reddit</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
</head>
<body>
<jsp:include page="header.jsp" />
<div th:include="header"/>
<div class="container">
<h1>Welcome, <small><sec:authentication property="principal.username" /></small></h1>
<br>
<h1>Welcome, <small><span sec:authentication="principal.username">Bob</span></small></h1>
<br/>
<a href="posts" class="btn btn-primary">My Scheduled Posts</a>
<a href="post" class="btn btn-primary">Post to Reddit</a>
<a href="postSchedule" class="btn btn-primary">Schedule Post to Reddit</a>

View File

@ -1,16 +1,12 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<html>
<head>
<title>Schedule to Reddit</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
</head>
<body>
<jsp:include page="header.jsp" />
<div th:include="header"/>
<div class="container">
<h1>My Scheduled Posts</h1>
@ -23,21 +19,20 @@
<th>Actions</th>
</tr>
</thead>
<c:forEach var="post" items="${posts}" >
<tr <c:if test="${post.isSent()}"> class="success"</c:if>>
<td><c:out value="${post.getTitle()}"/></td>
<td><fmt:formatDate type="both" dateStyle="long" timeStyle="long" value="${post.getSubmissionDate()}" /></td>
<td><c:out value="${post.getSubmissionResponse()}"/></td>
<tr th:each="post : ${posts}">
<td th:text="${post.getTitle()}"></td>
<td th:text="${#calendars.format(post.getSubmissionDate(),'dd MMMM yyyy HH:mm z')}"></td>
<td th:text="${post.getSubmissionResponse()}"></td>
<td>
<a href="editPost/${post.getId()}" class="btn btn-warning" >Edit</a>
<a href="#" class="btn btn-danger" onclick="confirmDelete(${post.getId()})">Delete</a>
<a th:href="@{/editPost/{id}(id=${post.getId()})}" class="btn btn-warning" >Edit</a>
<a href="#" class="btn btn-danger" th:onclick="'javascript:confirmDelete(\'' +${post.getId()}+ '\') '">Delete</a>
</td>
</tr>
</c:forEach>
</table>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
/*<![CDATA[*/
function confirmDelete(id) {
if (confirm("Do you really want to delete this post?") == true) {
deletePost(id);
@ -53,6 +48,7 @@ function deletePost(id){
}
});
}
/*]]>*/
</script>
</body>
</html>

View File

@ -1,16 +1,13 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<html>
<head>
<title>Schedule to Reddit</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="<c:url value="/resources/datetime-picker.css" />">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
<link rel="stylesheet" th:href="@{/resources/datetime-picker.css}"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="<c:url value="/resources/datetime-picker.js" />"></script>
<script src="<c:url value="/resources/validator.js" />"></script>
<script th:src="@{/resources/datetime-picker.js}"></script>
<script th:src="@{/resources/validator.js}"></script>
<style type="text/css">
.btn.disabled{
background-color: #ddd;
@ -24,7 +21,7 @@ border-color: #ddd;
</style>
</head>
<body>
<jsp:include page="header.jsp" />
<div th:include="header"/>
<div class="container">
<h1>Schedule Post to Reddit</h1>
@ -32,36 +29,36 @@ border-color: #ddd;
<div class="row">
<div class="form-group">
<label class="col-sm-3">Title</label>
<span class="col-sm-9"><input name="title" placeholder="title" class="form-control" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="title" placeholder="title" class="form-control" required="required" data-minlength="3"/></span>
</div>
<br><br>
<br/><br/>
<div class="form-group">
<label class="col-sm-3">Url</label>
<span class="col-sm-9"><input name="url" type="url" placeholder="url" class="form-control" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="url" type="url" placeholder="url" class="form-control" required="required" data-minlength="3"/></span>
</div>
<br><br>
<br/><br/>
<div class="form-group">
<label class="col-sm-3">Subreddit</label>
<span class="col-sm-9"><input name="sr" placeholder="Subreddit (e.g. kitten)" class="form-control" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="sr" placeholder="Subreddit (e.g. kitten)" class="form-control" required="required" data-minlength="3"/></span>
</div>
<br><br>
<br/><br/>
<div>
<label class="col-sm-3">Send replies to my inbox</label> <span class="col-sm-9"><input type="checkbox" name="sendreplies" value="true"/></span>
</div>
<br>
<br/>
<hr/>
<br>
<br/>
<div class="form-group">
<label class="col-sm-3">Resubmit If:</label>
<span class="col-sm-2">Votes didn't exceed </span>
<span class="col-sm-1">
<input type="number" class="form-control input-sm" value="0" name="score" required/>
<input type="number" class="form-control input-sm" value="0" name="score" required="required"/>
</span>
<span class="col-sm-3">within &nbsp;&nbsp;
<select name="interval">
<option value="0" selected>None</option>
<option value="0" selected="selected">None</option>
<option value="45">45 minutes</option>
<option value="60">1 hour</option>
<option value="120">2 hours</option>
@ -70,7 +67,7 @@ border-color: #ddd;
<span class="col-sm-3">try resubmitting &nbsp;&nbsp;
<select name="attempt">
<option value="0" selected>No</option>
<option value="0" selected="selected">No</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
@ -81,18 +78,20 @@ border-color: #ddd;
</div>
<br><br>
<br/><br/>
<label class="col-sm-3">Submission Date</label>
<span class="col-sm-9"><input type="text" name="date" class="form-control" readonly></span>
<span class="col-sm-9"><input type="text" name="date" class="form-control" readonly="readonly"/></span>
<script type="text/javascript">
/*<![CDATA[*/
$(function(){
$('*[name=date]').appendDtpicker({"inline": true});
});
/*]]>*/
</script>
<br><br>
<br/><br/>
<button type="submit" class="btn btn-primary">Schedule</button>

View File

@ -1,13 +1,10 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<html>
<head>
<title>Schedule to Reddit</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="<c:url value="/resources/validator.js" />"></script>
<script th:src="@{/resources/validator.js}"></script>
<style type="text/css">
.btn.disabled{
background-color: #ddd;
@ -21,7 +18,7 @@ border-color: #ddd;
</style>
</head>
<body>
<jsp:include page="header.jsp" />
<div th:include="header"/>
<div class="container">
<h1>Post to Reddit</h1>
@ -29,45 +26,46 @@ border-color: #ddd;
<div class="row">
<div class="form-group">
<label class="col-sm-3">Title</label>
<span class="col-sm-9"><input name="title" placeholder="title" class="form-control" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="title" placeholder="title" class="form-control" data-minlength="3" required="required"/></span>
</div>
<br><br>
<br/><br/>
<div class="form-group">
<label class="col-sm-3">Url</label>
<span class="col-sm-9"><input name="url" type="url" placeholder="url" class="form-control" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="url" type="url" placeholder="url" class="form-control" data-minlength="3" required="required"/></span>
</div>
<br><br>
<br/><br/>
<div class="form-group">
<label class="col-sm-3">Subreddit</label>
<span class="col-sm-9"><input name="sr" placeholder="Subreddit (e.g. kitten)" class="form-control" required data-minlength="3"/></span>
<span class="col-sm-9"><input name="sr" placeholder="Subreddit (e.g. kitten)" class="form-control" data-minlength="3" required="required"/></span>
</div>
<br><br>
<br/><br/>
<div>
<label class="col-sm-3">Send replies to my inbox</label> <span class="col-sm-9"><input type="checkbox" name="sendreplies" value="true"/></span>
</div>
<br><br>
<br/><br/>
<c:if test="${iden != null}">
<div th:if="${iden != null}">
<input type="hidden" name="iden" value="${iden}"/>
<div class="form-group">
<label class="col-sm-3">Captcha</label>
<span class="col-sm-9"><input name="captcha" placeholder="captcha" class="form-control"/></span>
</div>
<br><br>
<br/><br/>
<img src="http://www.reddit.com/captcha/${iden}" alt="captcha" width="200"/>
</c:if>
<br><br>
</div>
<br/><br/>
<span class="col-sm-3"><button id="submitbtn" type="submit" class="btn btn-primary">Post</button></span>
</div>
</form>
<div>
<c:if test="${PREDICTION_FEATURE.isActive()}">
<div th:if="${session.PREDICTION_FEATURE.isActive()}">
<button id="checkbtn" class="btn btn-default disabled" onclick="predicateResponse()">Predicate Response</button>
<span id="prediction"></span>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
$("input").change(function() {
if($("#submitbtn").hasClass("disabled")){
if(! $("#checkbtn").hasClass("disabled")){
@ -82,12 +80,13 @@ function predicateResponse(){
var domain = $('input[name="url"]').val();
domain = $('<a>').prop('href', domain).prop('hostname');
console.log(domain);
$.post("<c:url value="/predicatePostResponse"></c:url>",{title: title, domain: domain} ,function(data){
$.post("predicatePostResponse",{title: title, domain: domain} ,function(data){
$("#prediction").addClass("alert alert-info").html(data.replace('{','').replace('}',''));
});
}
/*]]>*/
</script>
</c:if>
</div>
</div>
</div>
</body>

View File

@ -1,17 +1,14 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<html>
<head>
<title>Schedule to Reddit</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
</head>
<body>
<jsp:include page="header.jsp" />
<div th:include="header"/>
<div class="container">
<h1>${msg}</h1>
<h1 th:text="${msg}">Hello</h1>
</div>
</body>
</html>

View File

@ -1,11 +1,9 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Schedule to Reddit</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
</head>
<body>
<div class="container">

View File

@ -6,9 +6,10 @@ import java.io.IOException;
import org.baeldung.reddit.classifier.RedditClassifier;
import org.baeldung.reddit.classifier.RedditDataCollector;
import org.junit.Ignore;
import org.junit.Test;
//@Ignore
@Ignore
public class RedditClassifierTest {
@Test

View File

@ -8,13 +8,11 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import org.baeldung.config.PersistenceJPAConfig;
import org.baeldung.persistence.dao.PostRepository;
import org.baeldung.persistence.dao.UserRepository;
import org.baeldung.persistence.model.Post;
import org.baeldung.persistence.model.User;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@ -24,10 +22,10 @@ import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceJPAConfig.class })
@ContextConfiguration(classes = { TestJPAConfig.class })
@Transactional
@TransactionConfiguration
@Ignore
// @Ignore
public class PersistenceJPATest {
@Autowired
private PostRepository postRepository;

View File

@ -0,0 +1,73 @@
package org.baeldung.persistence;
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-test.properties" })
@ComponentScan({ "org.baeldung.persistence.model", "org.baeldung.persistence.dao" })
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao")
public class TestJPAConfig {
@Autowired
private Environment env;
public TestJPAConfig() {
super();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
@Bean
public JpaTransactionManager transactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto", "create-drop"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
return hibernateProperties;
}
}