Package org.b3log.solo.jsonrpc.impl

Source Code of org.b3log.solo.jsonrpc.impl.BlogSyncService$SingletonHolder

/*
* Copyright (c) 2009, 2010, 2011, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.jsonrpc.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Keys;
import org.b3log.latke.action.ActionException;
import org.b3log.latke.action.util.PageCaches;
import org.b3log.latke.model.User;
import org.b3log.latke.repository.Transaction;
import org.b3log.solo.action.StatusCodes;
import org.b3log.solo.jsonrpc.AbstractGAEJSONRpcService;
import org.b3log.solo.util.Articles;
import org.b3log.solo.util.Tags;
import org.b3log.solo.model.Article;
import static org.b3log.solo.model.BlogSync.*;
import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.BlogSyncManagementRepository;
import org.b3log.solo.repository.ExternalArticleSoloArticleRepository;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.repository.impl.ArticleGAERepository;
import org.b3log.solo.repository.impl.BlogSyncMgmtGAERepository;
import org.b3log.solo.repository.impl.ExternalArticleSoloArticleGAERepository;
import org.b3log.solo.sync.BlogFactory;
import org.b3log.solo.sync.MetaWeblog;
import org.b3log.solo.sync.Post;
import org.b3log.solo.util.ArchiveDates;
import org.b3log.solo.util.Statistics;
import org.b3log.solo.util.Users;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
* Blog sync service for JavaScript client.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.8, Jan 12, 2011
*/
public final class BlogSyncService extends AbstractGAEJSONRpcService {

    /**
     * Logger.
     */
    private static final Logger LOGGER =
            Logger.getLogger(BlogSyncService.class.getName());
    /**
     * Article repository.
     */
    private ArticleRepository articleRepository =
            ArticleGAERepository.getInstance();
    /**
     * Tag utilities.
     */
    private Tags tagUtils = Tags.getInstance();
    /**
     * Article utilities.
     */
    private Articles articleUtils = Articles.getInstance();
    /**
     * Statistic utilities.
     */
    private Statistics statistics = Statistics.getInstance();
    /**
     * Archive date utilities.
     */
    private ArchiveDates archiveDateUtils = ArchiveDates.getInstance();
    /**
     * External blog article-Solo article repository.
     */
    private ExternalArticleSoloArticleRepository externalArticleSoloArticleRepository =
            ExternalArticleSoloArticleGAERepository.getInstance();
    /**
     * Blog sync management repository.
     */
    private BlogSyncManagementRepository blogSyncManagementRepository =
            BlogSyncMgmtGAERepository.getInstance();
    /**
     * User utilities.
     */
    private Users userUtils = Users.getInstance();
    /**
     * External blog article retrieval count incremental.
     */
    public static final int EXTERNAL_ARTICLE_RETRIEVAL_COUNT_INCREMENTAL = 2;

    /**
     * Gets blog sync management for external blogging system with the specified
     * http servlet request and http servlet response.
     *
     * @param requestJSONObject the specified request json object, for example,
     * <pre>
     * {
     *     ""blogSyncExternalBloggingSys": ""
     * }
     * </pre>
     * @param request the specified http servlet request
     * @param response the specified http servlet response
     * @return for example,
     * <pre>
     * {
     *     "blogSyncExternalBloggingSys": "",
     *     "blogSyncExternalBloggingSysUserName": "",
     *     "blogSyncExternalBloggingSysUserPassword": "",
     *     "blogSyncMgmtAddEnabled": boolean,
     *     "blogSyncMgmtUpdateEnabled": boolean,
     *     "blogSyncMgmtRemoveEnabled": boolean
     * }, returns {@code null} if not found
     * </pre>
     * @throws ActionException action exception
     * @throws IOException io exception
     */
    public JSONObject getBlogSyncMgmt(final JSONObject requestJSONObject,
                                      final HttpServletRequest request,
                                      final HttpServletResponse response)
            throws ActionException, IOException {
        final JSONObject ret = new JSONObject();
        if (!userUtils.isAdminLoggedIn()) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return ret;
        }

        String externalSys = null;
        try {
            externalSys = requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS);
            return blogSyncManagementRepository.getByExternalBloggingSystem(
                    externalSys);
        } catch (final JSONException e) {
            LOGGER.log(Level.SEVERE, e.getMessage(), e);
        }

        return null;
    }

    /**
     * Sets blog sync management for external blogging system with the specified
     * request json object, http servlet request and http servlet response.
     *
     * @param requestJSONObject the specified request json object, for example,
     * <pre>
     * {
     *     ""blogSyncExternalBloggingSys": "",
     *     "blogSyncExternalBloggingSysUserName": "",
     *     "blogSyncExternalBloggingSysUserPassword": "",
     *     "blogSyncMgmtAddEnabled": boolean,
     *     "blogSyncMgmtUpdateEnabled": boolean,
     *     "blogSyncMgmtRemoveEnabled": boolean
     * }
     * </pre>
     * @param request the specified http servlet request
     * @param response the specified http servlet response
     * @return for example,
     * <pre>
     * {
     *     "sc": SET_BLOG_SYNC_MGMT_SUCC
     * }
     * </pre>
     * @throws ActionException action exception
     * @throws IOException io exception
     */
    public JSONObject setBlogSyncMgmt(final JSONObject requestJSONObject,
                                      final HttpServletRequest request,
                                      final HttpServletResponse response)
            throws ActionException, IOException {
        final JSONObject ret = new JSONObject();
        if (!userUtils.isAdminLoggedIn()) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return ret;
        }
        final Transaction transaction =
                blogSyncManagementRepository.beginTransaction();
        try {
            final String externalBloggingSys =
                    requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS);
            final String userName = requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS_USER_NAME);
            final String userPwd = requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS_USER_PASSWORD);
            final boolean addEnabled = requestJSONObject.getBoolean(
                    BLOG_SYNC_MGMT_ADD_ENABLED);
            final boolean updateEnabled = requestJSONObject.getBoolean(
                    BLOG_SYNC_MGMT_UPDATE_ENABLED);
            final boolean removeEnabled = requestJSONObject.getBoolean(
                    BLOG_SYNC_MGMT_REMOVE_ENABLED);

            JSONObject blogSyncMgmt = blogSyncManagementRepository.
                    getByExternalBloggingSystem(externalBloggingSys);
            if (null == blogSyncMgmt) {
                blogSyncMgmt = new JSONObject();
            }

            blogSyncMgmt.put(BLOG_SYNC_EXTERNAL_BLOGGING_SYS,
                             externalBloggingSys);
            blogSyncMgmt.put(BLOG_SYNC_EXTERNAL_BLOGGING_SYS_USER_NAME,
                             userName);
            blogSyncMgmt.put(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS_USER_PASSWORD, userPwd);
            blogSyncMgmt.put(BLOG_SYNC_MGMT_ADD_ENABLED, addEnabled);
            blogSyncMgmt.put(BLOG_SYNC_MGMT_UPDATE_ENABLED,
                             updateEnabled);
            blogSyncMgmt.put(BLOG_SYNC_MGMT_REMOVE_ENABLED,
                             removeEnabled);

            if (!blogSyncMgmt.has(Keys.OBJECT_ID)) {
                blogSyncManagementRepository.add(blogSyncMgmt);
                LOGGER.log(Level.FINER,
                           "Added blog sync management for [{0}] [{1}]",
                           new String[]{
                            externalBloggingSys,
                            blogSyncMgmt.toString(
                            SoloServletListener.JSON_PRINT_INDENT_FACTOR)
                        });

            } else {
                blogSyncManagementRepository.update(
                        blogSyncMgmt.getString(Keys.OBJECT_ID),
                        blogSyncMgmt);
                LOGGER.log(Level.FINER,
                           "Updated blog sync management for [{0}] [{1}]",
                           new String[]{
                            externalBloggingSys,
                            blogSyncMgmt.toString(
                            SoloServletListener.JSON_PRINT_INDENT_FACTOR)
                        });
            }

            transaction.commit();
            ret.put(Keys.STATUS_CODE,
                    StatusCodes.SET_BLOG_SYNC_MGMT_SUCC);
        } catch (final Exception e) {
            if (transaction.isActive()) {
                transaction.rollback();
            }
            LOGGER.log(Level.SEVERE, e.getMessage(), e);
            throw new ActionException(e);
        }

        return ret;
    }

    /**
     * Imports external blogging system articles by the specified request json
     * object and http servlet request.
     *
     * @param requestJSONObject the specified request json object, for example,
     * <pre>
     * {
     *     "blogSyncExternalBloggingSys": "",
     *     "oIds": ["", "", ....]
     * }
     * </pre>
     * @param request the specified http servlet request
     * @param response the specified http servlet response
     * @return imported article ids, for example,
     * <pre>
     * {
     *     "oIds": ["", "", ....]
     * }
     * </pre>
     * @throws ActionException action exception
     * @throws IOException io exception
     */
    public JSONObject importExternalArticles(final JSONObject requestJSONObject,
                                             final HttpServletRequest request,
                                             final HttpServletResponse response)
            throws ActionException, IOException {
        final JSONObject ret = new JSONObject();
        if (!userUtils.isAdminLoggedIn()) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return ret;
        }

        try {
            final String blogSyncExternalBloggingSys =
                    requestJSONObject.getString(BLOG_SYNC_EXTERNAL_BLOGGING_SYS);
            final JSONArray articleIds = requestJSONObject.getJSONArray(
                    Keys.OBJECT_IDS);
            final List<String> importedIds = new ArrayList<String>();
            for (int i = 0; i < articleIds.length(); i++) {
                final Transaction transaction =
                        articleRepository.beginTransaction();
                try {
                    final String oId = articleIds.getString(i);
                    final JSONObject externalArticle =
                            externalArticleSoloArticleRepository.
                            getBySoloArticleId(oId, blogSyncExternalBloggingSys);
                    externalArticle.put(BLOG_SYNC_EXTERNAL_ARTICLE_IMPORTED,
                                        true);
                    externalArticleSoloArticleRepository.update(
                            externalArticle.getString(Keys.OBJECT_ID),
                            externalArticle);
                    final JSONObject soloArticle =
                            toSoloArticle(externalArticle);

                    final String categoriesString = externalArticle.getString(
                            BLOG_SYNC_EXTERNAL_ARTICLE_CATEGORIES);
                    final String[] tagTitles = categoriesString.split(",");
                    final JSONArray tags = tagUtils.tag(tagTitles, soloArticle);
                    articleUtils.addTagArticleRelation(tags, soloArticle);

                    articleRepository.importArticle(soloArticle);
                    importedIds.add(oId);

                    statistics.incBlogArticleCount();
                    statistics.incPublishedBlogArticleCount();

                    archiveDateUtils.archiveDate(soloArticle);

                    transaction.commit();
                } catch (final Exception e) {
                    LOGGER.log(Level.SEVERE, e.getMessage(), e);
                    if (transaction.isActive()) {
                        transaction.rollback();
                    }
                }
            }

            PageCaches.removeAll();
            ret.put(Keys.OBJECT_IDS, importedIds);
        } catch (final JSONException e) {
            LOGGER.log(Level.SEVERE, e.getMessage(), e);
            throw new ActionException(e);
        }

        return ret;
    }

    /**
     * Gest external blogging system articles by the specified request json
     * object.
     *
     * @param requestJSONObject the specified request json object, for example,
     * <pre>
     * {
     *     "blogSyncExternalBloggingSys": "",
     *     "blogSyncExternalBloggingSysUserName": "",
     *     "blogSyncExternalBloggingSysUserPassword": "",
     *     "blogSyncExternalArchiveDate": "2006/12"
     * }
     * </pre>
     * @param request the specified http servlet request
     * @param response the specified http servlet response
     * @return for example,
     * <pre>
     * {
     *     "blogSyncExternalArticles": [{
     *         "oId": "",
     *         "blogSyncExternalArticleTitle": "",
     *         "blogSyncExternalArticleCreateDate": java.util.Date,
     *         "blogSyncExternalArticleCategories": "category1, category2, ....",
     *         "blogSyncExternalArticleContent": "",
     *         "blogsyncExternalArticleAbstract": ""
     *     }, ....]
     * }
     * </pre>
     * @throws ActionException action exception
     * @throws IOException io exception
     */
    public JSONObject getExternalArticlesByArchiveDate(
            final JSONObject requestJSONObject,
            final HttpServletRequest request,
            final HttpServletResponse response) throws ActionException,
                                                       IOException {
        final JSONObject ret = new JSONObject();
        if (!userUtils.isAdminLoggedIn()) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return ret;
        }

        final Transaction transaction =
                externalArticleSoloArticleRepository.beginTransaction();

        try {
            final String externalSys = requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS);
            final String userName =
                    requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS_USER_NAME);
            final String userPwd =
                    requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS_USER_PASSWORD);
            final String archiveDate = requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_ARCHIVE_DATE);
            final MetaWeblog metaWeblog = BlogFactory.getMetaWeblog(externalSys);
            metaWeblog.setUserName(userName);
            metaWeblog.setUserPassword(userPwd);
            final List<String> externalArticleIds =
                    metaWeblog.getArticleIdsByArchiveDate(archiveDate);
            LOGGER.log(Level.FINER,
                       "There are [{0}] articles of [{1}] user[userName={2}] in [{3}]",
                       new Object[]{externalArticleIds.size(),
                                    externalSys,
                                    userName,
                                    archiveDate});
            final JSONArray articles = new JSONArray();
            ret.put(BLOG_SYNC_EXTERNAL_ARTICLES, articles);
            int retrievalCnt = 0;
            for (final String externalArticleId : externalArticleIds) {
                final JSONObject soloArticle =
                        externalArticleSoloArticleRepository.getSoloArticle(
                        externalArticleId, externalSys);
                JSONObject article = null;
                boolean imported = false;
                if (null != soloArticle) {
                    article = soloArticle;
                    imported = soloArticle.getBoolean(
                            BLOG_SYNC_EXTERNAL_ARTICLE_IMPORTED);
                } else { // Not retrieved yet, get the article from External blogging system
                    final Post externalPost =
                            metaWeblog.getPost(externalArticleId);
                    if (null == externalPost) {
                        LOGGER.log(Level.WARNING,
                                   "Retrieve article[postId={0}] from external blogging system[{1}] is null",
                                   new String[]{externalArticleId, externalSys});
                        continue;
                    }

                    article = externalPost.toJSONObject();
                    final JSONObject externalArticleSoloArticleRelation =
                            new JSONObject();
                    externalArticleSoloArticleRelation.put(
                            BLOG_SYNC_EXTERNAL_ARTICLE_IMPORTED, false);
                    externalArticleSoloArticleRelation.put(
                            BLOG_SYNC_EXTERNAL_ARTICLE_ID,
                            externalArticleId);
                    externalArticleSoloArticleRelation.put(
                            Article.ARTICLE + "_" + Keys.OBJECT_ID,
                            article.getString(Keys.OBJECT_ID));
                    externalArticleSoloArticleRelation.put(
                            BLOG_SYNC_EXTERNAL_BLOGGING_SYS, externalSys);

                    externalArticleSoloArticleRelation.put(
                            BLOG_SYNC_EXTERNAL_ARTICLE_ABSTRACT,
                            article.getString(
                            BLOG_SYNC_EXTERNAL_ARTICLE_ABSTRACT));
                    externalArticleSoloArticleRelation.put(
                            BLOG_SYNC_EXTERNAL_ARTICLE_CATEGORIES,
                            article.getString(
                            BLOG_SYNC_EXTERNAL_ARTICLE_CATEGORIES));
                    externalArticleSoloArticleRelation.put(
                            BLOG_SYNC_EXTERNAL_ARTICLE_CONTENT,
                            article.getString(
                            BLOG_SYNC_EXTERNAL_ARTICLE_CONTENT));
                    externalArticleSoloArticleRelation.put(
                            BLOG_SYNC_EXTERNAL_ARTICLE_CREATE_DATE,
                            article.get(
                            BLOG_SYNC_EXTERNAL_ARTICLE_CREATE_DATE));
                    externalArticleSoloArticleRelation.put(
                            BLOG_SYNC_EXTERNAL_ARTICLE_TITLE,
                            article.getString(BLOG_SYNC_EXTERNAL_ARTICLE_TITLE));

                    externalArticleSoloArticleRepository.add(
                            externalArticleSoloArticleRelation);
                    LOGGER.log(Level.INFO,
                               "Saved a external article into tmp repository");
                    LOGGER.log(Level.FINEST,
                               "The external article[relation={0}]",
                               externalArticleSoloArticleRelation.toString(
                            SoloServletListener.JSON_PRINT_INDENT_FACTOR));

                    retrievalCnt++;
                }

                article.put(BLOG_SYNC_IMPORTED, imported);
                articles.put(article);

                if (EXTERNAL_ARTICLE_RETRIEVAL_COUNT_INCREMENTAL
                    == retrievalCnt) {
                    break;
                }
            }

            transaction.commit();
        } catch (final Exception e) {
            if (transaction.isActive()) {
                transaction.rollback();
            }
            LOGGER.log(Level.SEVERE, e.getMessage(), e);
            throw new ActionException(e);
        }

        return ret;
    }

    /**
     * Gets external blogging system article archive dates by the specified
     * request json object.
     *
     * @param requestJSONObject the specified request json object, for example,
     * <pre>
     * {
     *     "blogSyncExternalBloggingSys": "",
     *     "blogSyncExternalBloggingSysUserName": ""
     * }
     * </pre>
     * @param request the specified http servlet request
     * @param response the specified http servlet response
     * @return for example,
     * <pre>
     * {
     *     "blogSyncExternalArchiveDates": ["2006/12", "2007/01", ...]
     * }
     * </pre>
     * @throws ActionException action exception
     * @throws IOException io exception
     */
    public JSONObject getExternalArticleArchiveDate(
            final JSONObject requestJSONObject,
            final HttpServletRequest request,
            final HttpServletResponse response) throws ActionException,
                                                       IOException {
        final JSONObject ret = new JSONObject();
        if (!userUtils.isAdminLoggedIn()) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return ret;
        }

        try {
            final String externalSys = requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS);
            final String userName = requestJSONObject.getString(
                    BLOG_SYNC_EXTERNAL_BLOGGING_SYS_USER_NAME);
            final MetaWeblog metaWeblog = BlogFactory.getMetaWeblog(externalSys);
            metaWeblog.setUserName(userName);
            metaWeblog.setUserPassword("ignored");
            final List<String> archiveDates = metaWeblog.getArchiveDates();

            ret.put(BLOG_SYNC_EXTERNAL_ARCHIVE_DATES, archiveDates);
        } catch (final JSONException e) {
            LOGGER.log(Level.SEVERE, e.getMessage(), e);
            throw new ActionException(e);
        }

        return ret;
    }

    /**
     * To B3log Solo article(Key transformation) for the specified external blog
     * article.
     *
     * @param externalArticle the specified external Blog article
     * @return Solo article
     * @throws Exception exception
     */
    private JSONObject toSoloArticle(final JSONObject externalArticle)
            throws Exception {
        final JSONObject ret = new JSONObject();
        final String articleId = externalArticle.getString(Article.ARTICLE
                                                           + "_"
                                                           + Keys.OBJECT_ID);
        ret.put(Keys.OBJECT_ID, articleId);
        ret.put(Article.ARTICLE_TITLE,
                externalArticle.getString(BLOG_SYNC_EXTERNAL_ARTICLE_TITLE));
        ret.put(Article.ARTICLE_ABSTRACT,
                externalArticle.getString(BLOG_SYNC_EXTERNAL_ARTICLE_ABSTRACT));
        ret.put(Article.ARTICLE_CONTENT,
                externalArticle.getString(BLOG_SYNC_EXTERNAL_ARTICLE_CONTENT));
        final Date createDate = (Date) externalArticle.get(
                BLOG_SYNC_EXTERNAL_ARTICLE_CREATE_DATE);
        ret.put(Article.ARTICLE_CREATE_DATE, createDate);
        ret.put(Article.ARTICLE_UPDATE_DATE, createDate);
        ret.put(Article.ARTICLE_TAGS_REF,
                externalArticle.getString(BLOG_SYNC_EXTERNAL_ARTICLE_CATEGORIES));

        ret.put(Article.ARTICLE_VIEW_COUNT, 0);
        ret.put(Article.ARTICLE_COMMENT_COUNT, 0);
        final String permalinkDate =
                ArticleService.PERMALINK_FORMAT.format(createDate);
        final String permalink = "/articles/" + permalinkDate + "/"
                                 + articleId + ".html";
        ret.put(Article.ARTICLE_PERMALINK, permalink);
        ret.put(Article.ARTICLE_PUT_TOP, false);
        ret.put(Article.ARTICLE_IS_PUBLISHED, true);
        ret.put(Article.ARTICLE_HAD_BEEN_PUBLISHED, true);
        final JSONObject currentUser = userUtils.getCurrentUser();
        final String currentUserEmail = currentUser.getString(User.USER_EMAIL);
        ret.put(Article.ARTICLE_AUTHOR_EMAIL, currentUserEmail);

        return ret;
    }

    /**
     * Gets the {@link BlogSyncService} singleton.
     *
     * @return the singleton
     */
    public static BlogSyncService getInstance() {
        return SingletonHolder.SINGLETON;
    }

    /**
     * Private default constructor.
     */
    private BlogSyncService() {
    }

    /**
     * Singleton holder.
     *
     * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
     * @version 1.0.0.0, Jan 12, 2011
     */
    private static final class SingletonHolder {

        /**
         * Singleton.
         */
        private static final BlogSyncService SINGLETON = new BlogSyncService();

        /**
         * Private default constructor.
         */
        private SingletonHolder() {
        }
    }
}
TOP

Related Classes of org.b3log.solo.jsonrpc.impl.BlogSyncService$SingletonHolder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.