/**
* myJerry | Evenstar
* Copyright (C) 2010 myJerry Development Team
* http://www.myjerry.org
*
* The file is licensed under the the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.myjerry.evenstar.service.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import org.myjerry.evenstar.helper.SortHelper;
import org.myjerry.evenstar.model.Blog;
import org.myjerry.evenstar.model.BlogPost;
import org.myjerry.evenstar.model.BlogPostLabelMapping;
import org.myjerry.evenstar.persistence.PersistenceManagerFactoryImpl;
import org.myjerry.evenstar.service.BlogLabelService;
import org.myjerry.evenstar.service.BlogPostService;
import org.myjerry.evenstar.service.BlogService;
import org.myjerry.evenstar.service.UserService;
import org.myjerry.util.GAEUserUtil;
import org.myjerry.util.ServerUtils;
import org.myjerry.util.StringUtils;
import org.myjerry.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query.FilterOperator;
public class BlogPostServiceImpl implements BlogPostService {
@Autowired
private BlogService blogService;
@Autowired
private BlogLabelService blogLabelService;
@Autowired
private UserService userService;
@Override
public boolean publishPost(BlogPost blogPost) {
if(blogPost.getCreationDate() == null) {
blogPost.setCreationDate(ServerUtils.getServerDate());
}
blogPost.setLastUpdated(ServerUtils.getServerDate());
blogPost.setLastUpdateUser(StringUtils.getLong(GAEUserUtil.getUserID()));
if(blogPost.getPostedDate() == null) {
blogPost.setPostedDate(ServerUtils.getServerDate());
}
if(StringUtils.isEmpty(blogPost.getUrl())) {
// this also means that we need to create a new URL for this service
int year = blogPost.getPostedDate().getYear() + 1900;
int month = blogPost.getPostedDate().getMonth() + 1;
String prefix = WebUtils.getUrlStringFromPostTitle(blogPost.getTitle());
String url = null;
if(StringUtils.isNotEmpty(prefix)) {
url = "/" + year + "/" + month + "/" + prefix;
}
Blog blog = this.blogService.getBlog(blogPost.getBlogID());
if(StringUtils.isNotEmpty(blog.getAlias()) && StringUtils.isNotEmpty(url)) {
url = "/" + blog.getAlias() + url;
}
blogPost.setUrl(url);
if(StringUtils.isEmpty(url)) {
blogPost.setPostedDate(null);
}
} else {
char firstChar = blogPost.getUrl().charAt(0);
if(firstChar != '/') {
blogPost.setUrl("/" + blogPost.getUrl());
}
}
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
try {
if(blogPost.getPostID() == null) {
// create a new post
manager.makePersistent(blogPost);
// update the labels
this.blogLabelService.updatePostLabels(blogPost.getBlogID(), blogPost.getPostID(), null, blogPost.getLabels());
} else {
// this post should be updated
Key key = KeyFactory.createKey(BlogPost.class.getSimpleName(), blogPost.getPostID());
BlogPost post = manager.getObjectById(BlogPost.class, key);
String oldLabels = post.getLabels();
post.setContents(blogPost.getContents());
post.setLabels(blogPost.getLabels());
post.setTitle(blogPost.getTitle());
post.setUrl(blogPost.getUrl());
post.setLastUpdated(blogPost.getLastUpdated());
post.setLastUpdateUser(blogPost.getLastUpdateUser());
post.setPostedDate(blogPost.getPostedDate());
post.setPrivacyMode(blogPost.getPrivacyMode());
// update the labels
this.blogLabelService.updatePostLabels(blogPost.getBlogID(), blogPost.getPostID(), oldLabels, blogPost.getLabels());
manager.makePersistent(post);
}
return true;
} catch(Exception e) {
e.printStackTrace();
} finally {
manager.close();
}
return false;
}
@Override
public boolean deletePost(Long blogPostID, Long blogID) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
try {
Key key = KeyFactory.createKey(BlogPost.class.getSimpleName(), blogPostID);
BlogPost post = manager.getObjectById(BlogPost.class, key);
if(post.getBlogID().equals(blogID)) {
// delete labels for post
this.blogLabelService.deleteLabelsForPost(post.getBlogID(), post.getPostID(), post.getLabels());
// delete the post itself
manager.deletePersistent(post);
return true;
}
} catch(Exception e) {
e.printStackTrace();
} finally {
manager.close();
}
return false;
}
@Override
public boolean saveDraftPost(BlogPost blogPost) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
try {
if(blogPost.getPostID() == null) {
// create a new post
if(blogPost.getCreationDate() == null) {
blogPost.setCreationDate(ServerUtils.getServerDate());
}
blogPost.setLastUpdated(ServerUtils.getServerDate());
blogPost.setLastUpdateUser(StringUtils.getLong(GAEUserUtil.getUserID()));
manager.makePersistent(blogPost);
} else {
// this post should be updated
Key key = KeyFactory.createKey(BlogPost.class.getSimpleName(), blogPost.getPostID());
BlogPost post = manager.getObjectById(BlogPost.class, key);
// overwrite this post object
post.setContents(blogPost.getContents());
post.setLabels(blogPost.getLabels());
post.setLastUpdated(ServerUtils.getServerDate());
post.setLastUpdateUser(StringUtils.getLong(GAEUserUtil.getUserID()));
post.setTitle(blogPost.getTitle());
post.setPrivacyMode(blogPost.getPrivacyMode());
manager.makePersistent(post);
}
return true;
} catch(Exception e) {
e.printStackTrace();
} finally {
manager.close();
}
return false;
}
@Override
public boolean schedulePost(BlogPost blogPost) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean unPublishPost(Long blogPostID, Long blogID) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
try {
Key key = KeyFactory.createKey(BlogPost.class.getSimpleName(), blogPostID);
BlogPost post = manager.getObjectById(BlogPost.class, key);
if(post.getBlogID().equals(blogID)) {
post.setPostedDate(null);
// delete labels for post
this.blogLabelService.deleteLabelsForPost(post.getBlogID(), post.getPostID(), post.getLabels());
}
return true;
} catch(Exception e) {
e.printStackTrace();
} finally {
manager.close();
}
return false;
}
/**
* Due to GAE Datastore restrictions only max 1000 posts will be returned by this method.
* Use the {@link #getBlogPosts(Long, long, long)} method instead.
*/
@SuppressWarnings("unchecked")
@Override
public Collection<BlogPost> getAllBlogPosts(Long blogID) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
try {
Query query = manager.newQuery(BlogPost.class, "blogID == blogIDParam");
query.declareParameters("String blogIDParam");
List<BlogPost> blogs = (List<BlogPost>) query.execute(blogID);
return manager.detachCopyAll(blogs);
} catch(Exception e) {
e.printStackTrace();
} finally {
manager.close();
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public Collection<BlogPost> getBlogPosts(Long blogID, int count) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class);
query.setFilter("blogID == blogIDParam && postedDate != null");
query.setOrdering("postedDate desc");
query.declareParameters("String blogIDParam");
query.setRange(0, count + 1);
try {
List<BlogPost> posts = (List<BlogPost>) query.execute(blogID);
if(posts != null) {
// take care of a GAE Bug
for(BlogPost post : posts) {
post.getContents(); // trash this get :(
}
return manager.detachCopyAll(posts);
}
return posts;
} catch(Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
manager.close();
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public Collection<BlogPost> getBlogPosts(Long blogID, int count, Long olderThan, Long newerThan) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class);
query.setFilter("blogID == blogIDParam && postedDate != null");
query.setOrdering("postedDate desc");
query.declareParameters("String blogIDParam");
try {
List<BlogPost> allPosts = (List<BlogPost>) query.execute(blogID);
if(allPosts != null && allPosts.size() > 0) {
List<BlogPost> posts = new ArrayList<BlogPost>();
int length = count + 1;
if(length > allPosts.size()) {
length = allPosts.size();
}
for(int i=0; i < allPosts.size(); i++) {
BlogPost post = allPosts.get(i);
Date posted = post.getPostedDate();
if(posted != null) {
long time = posted.getTime();
if(olderThan != null && time > olderThan) {
continue;
}
if(newerThan != null && time < newerThan) {
continue;
}
post.getContents();
post = manager.detachCopy(post);
posts.add(post);
if(posts.size() == length) {
break;
}
}
}
return posts;
}
} catch(Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
manager.close();
}
return null;
}
@Override
public Collection<BlogPost> getBlogPostsForLabel(Long blogID, Long labelID, int count) {
return getBlogPostsForLabel(blogID, labelID, count, null, null);
}
@SuppressWarnings("unchecked")
@Override
public Collection<BlogPost> getBlogPostsForLabel(Long blogID, Long labelID, int count, Long olderThan, Long newerThan) {
DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
// get a list of all IDs that match this label
com.google.appengine.api.datastore.Query query = new com.google.appengine.api.datastore.Query(BlogPostLabelMapping.class.getSimpleName());
query.addFilter("blogID", FilterOperator.EQUAL, blogID);
query.addFilter("labelID", FilterOperator.EQUAL, labelID);
FetchOptions fetchOptions = FetchOptions.Builder.withOffset(0).limit(Integer.MAX_VALUE);
PreparedQuery preparedQuery = datastoreService.prepare(query);
List<Entity> list = preparedQuery.asList(fetchOptions);
List<Long> postIDs = new ArrayList<Long>();
if(list.size() > 0) {
for(Entity entity : list) {
Long id = (Long) entity.getProperty("postID");
postIDs.add(id);
}
}
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query q = manager.newQuery(BlogPost.class, ":p.contains(postID)");
List<BlogPost> allPosts = (List<BlogPost>) q.execute(postIDs);
SortHelper.sortPosts(allPosts);
// get first count + 1 objects
List<BlogPost> posts = new ArrayList<BlogPost>();
int length = count + 1;
if(length > allPosts.size()) {
length = allPosts.size();
}
for(int i=0; i < allPosts.size(); i++) {
BlogPost post = allPosts.get(i);
Date posted = post.getPostedDate();
if(posted != null) {
long time = posted.getTime();
if(olderThan != null && time > olderThan) {
continue;
}
if(newerThan != null && time < newerThan) {
continue;
}
post.getContents();
post = manager.detachCopy(post);
posts.add(post);
if(posts.size() == length) {
break;
}
}
}
return posts;
}
@SuppressWarnings("unchecked")
@Override
public Collection<BlogPost> getOlderBlogPosts(Long blogID, int count, Date lastUpdated) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class);
query.setFilter("blogID == blogIDParam && postedDate != null && postedDate <= postedDateParam");
query.setOrdering("postedDate desc");
query.declareImports("import java.util.Date");
query.declareParameters("String blogIDParam, Date postedDateParam");
query.setRange(0, count + 1);
try {
List<BlogPost> posts = (List<BlogPost>) query.execute(blogID, lastUpdated);
if(posts != null) {
// take care of a GAE Bug
for(BlogPost post : posts) {
post.getContents(); // trash this get :(
}
return manager.detachCopyAll(posts);
}
return posts;
} catch(Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
manager.close();
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public Collection<BlogPost> getNewerBlogPosts(Long blogID, int count, Date lastUpdated) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class);
query.setFilter("blogID == blogIDParam && postedDate != null && postedDate >= postedDateParam");
query.setOrdering("postedDate asc");
query.declareImports("import java.util.Date");
query.declareParameters("String blogIDParam, Date postedDateParam");
query.setRange(0, count + 1);
try {
List<BlogPost> posts = (List<BlogPost>) query.execute(blogID, lastUpdated);
if(posts != null) {
// take care of a GAE Bug
for(BlogPost post : posts) {
post.getContents(); // trash this get :(
}
return manager.detachCopyAll(posts);
}
return posts;
} catch(Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
manager.close();
}
return null;
}
@Override
public Long getTotalPosts(Long blogID) {
DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
com.google.appengine.api.datastore.Query query = new com.google.appengine.api.datastore.Query(BlogPost.class.getSimpleName());
query.setKeysOnly();
query.addFilter("blogID", FilterOperator.EQUAL, blogID);
FetchOptions fetchOptions = FetchOptions.Builder.withOffset(0).limit(Integer.MAX_VALUE);
PreparedQuery preparedQuery = datastoreService.prepare(query);
int size = preparedQuery.asList(fetchOptions).size();
return new Long(size);
}
@Override
public BlogPost getPost(Long blogPostID, Long blogID) {
if(blogPostID == null || blogID == null) {
return null;
}
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
try {
Key key = KeyFactory.createKey(BlogPost.class.getSimpleName(), blogPostID);
BlogPost post = manager.getObjectById(BlogPost.class, key);
if(post.getBlogID().equals(blogID)) {
post.getContents();
return manager.detachCopy(post);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
manager.close();
}
return null;
}
@Override
public boolean existsPost(Long postID, Long blogID) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
try {
Key key = KeyFactory.createKey(BlogPost.class.getSimpleName(), postID);
BlogPost post = manager.getObjectById(BlogPost.class, key);
if(post.getBlogID().equals(blogID)) {
return true;
}
} catch(Exception e) {
e.printStackTrace();
} finally {
manager.close();
}
return false;
}
@SuppressWarnings("unchecked")
@Override
public BlogPost getPostForURI(String uri) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class, "url == urlParam");
query.declareParameters("String urlParam");
try {
List<BlogPost> posts = (List<BlogPost>) query.execute(uri);
if(posts != null && posts.size() == 1) {
return manager.detachCopy(posts.get(0));
}
} catch(JDOObjectNotFoundException e) {
// do nothing
} catch(Exception e) {
e.printStackTrace();
} finally {
manager.close();
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public boolean isFirstPost(BlogPost post) {
if(post != null) {
Long blogID = post.getBlogID();
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class);
query.setFilter("blogID == blogIDParam && postedDate != null");
query.setOrdering("postedDate desc");
query.declareParameters("String blogIDParam");
query.setRange(0, 1);
try {
List<BlogPost> posts = (List<BlogPost>) query.execute(blogID);
if(posts != null && posts.size() == 1) {
if(posts.get(0).getPostID().equals(post.getPostID())) {
return true;
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
manager.close();
}
}
return false;
}
@SuppressWarnings("unchecked")
@Override
public Date getLastPublishedPostDate(Long blogID) {
if(blogID == null) {
return null;
}
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class, "blogID == blogIDParam && postedDate != null");
query.setOrdering("postedDate desc");
query.declareParameters("String blogIDParam");
query.setRange(0, 1);
try {
List<BlogPost> posts = (List<BlogPost>) query.execute(blogID);
if(posts != null && posts.size() == 1) {
return posts.get(0).getPostedDate();
}
} catch(Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
manager.close();
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public String getNewerPostUrl(Long blogID, Date date) {
if(blogID != null && date != null) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class, "blogID == blogIDParam && postedDate > postedDateParam");
query.setOrdering("postedDate asc");
query.declareImports("import java.util.Date");
query.declareParameters("Long blogIDParam, Date postedDateParam");
query.setRange(0, 1);
try {
List<BlogPost> posts = (List<BlogPost>) query.execute(blogID, date);
if(posts != null && posts.size() == 1) {
return posts.get(0).getUrl();
}
} catch(Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
manager.close();
}
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public String getOlderPostUrl(Long blogID, Date date) {
if(blogID != null && date != null) {
PersistenceManager manager = PersistenceManagerFactoryImpl.getPersistenceManager();
Query query = manager.newQuery(BlogPost.class, "blogID == blogIDParam && postedDate < postedDateParam");
query.setOrdering("postedDate desc");
query.declareImports("import java.util.Date");
query.declareParameters("Long blogIDParam, Date postedDateParam");
query.setRange(0, 1);
try {
List<BlogPost> posts = (List<BlogPost>) query.execute(blogID, date);
if(posts != null && posts.size() == 1) {
return posts.get(0).getUrl();
}
} catch(Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
manager.close();
}
}
return null;
}
/**
* @return the blogService
*/
public BlogService getBlogService() {
return blogService;
}
/**
* @param blogService the blogService to set
*/
public void setBlogService(BlogService blogService) {
this.blogService = blogService;
}
/**
* @return the blogLabelService
*/
public BlogLabelService getBlogLabelService() {
return blogLabelService;
}
/**
* @param blogLabelService the blogLabelService to set
*/
public void setBlogLabelService(BlogLabelService blogLabelService) {
this.blogLabelService = blogLabelService;
}
/**
* @return the userService
*/
public UserService getUserService() {
return userService;
}
/**
* @param userService the userService to set
*/
public void setUserService(UserService userService) {
this.userService = userService;
}
}