/*
* Symphony - A modern community (forum/SNS/blog) platform written in Java.
* Copyright (C) 2012-2017, b3log.org & hacpai.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.b3log.symphony.processor;
import org.b3log.latke.Keys;
import org.b3log.latke.ioc.inject.Inject;
import org.b3log.latke.model.User;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.advice.RequestProcessAdviceException;
import org.b3log.latke.servlet.annotation.After;
import org.b3log.latke.servlet.annotation.Before;
import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer;
import org.b3log.latke.util.Requests;
import org.b3log.symphony.model.Common;
import org.b3log.symphony.model.Link;
import org.b3log.symphony.model.Option;
import org.b3log.symphony.model.Tag;
import org.b3log.symphony.processor.advice.LoginCheck;
import org.b3log.symphony.processor.advice.PermissionGrant;
import org.b3log.symphony.processor.advice.stopwatch.StopwatchEndAdvice;
import org.b3log.symphony.processor.advice.stopwatch.StopwatchStartAdvice;
import org.b3log.symphony.service.DataModelService;
import org.b3log.symphony.service.LinkForgeMgmtService;
import org.b3log.symphony.service.LinkForgeQueryService;
import org.b3log.symphony.service.OptionQueryService;
import org.b3log.symphony.util.Symphonys;
import org.json.JSONObject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Link forge processor.
* <p>
* <ul>
* <li>Shows link forge (/link-forge), GET</li>
* <li>Submits a link into forge (/forge/link), POST</li>
* </ul>
* </p>
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @version 1.1.0.7, Dec 25, 2016
* @since 1.6.0
*/
@RequestProcessor
public class LinkForgeProcessor {
/**
* Forge thread.
*/
private static final ExecutorService FORGE_EXECUTOR_SERVICE = Executors.newFixedThreadPool(1);
/**
* Link forget management service.
*/
@Inject
private LinkForgeMgmtService linkForgeMgmtService;
/**
* Link forge query service.
*/
@Inject
private LinkForgeQueryService linkForgeQueryService;
/**
* Option query service.
*/
@Inject
private OptionQueryService optionQueryService;
/**
* Data model service.
*/
@Inject
private DataModelService dataModelService;
/**
* Submits a link into forge.
*
* @param context the specified context
* @throws Exception exception
*/
@RequestProcessing(value = "/forge/link", method = HTTPRequestMethod.POST)
@Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class})
@After(adviceClass = StopwatchEndAdvice.class)
public void forgeLink(final HTTPRequestContext context) throws Exception {
context.renderJSON(true);
JSONObject requestJSONObject;
try {
requestJSONObject = Requests.parseRequestJSONObject(context.getRequest(), context.getResponse());
} catch (final Exception e) {
throw new RequestProcessAdviceException(new JSONObject().put(Keys.MSG, e.getMessage()));
}
final JSONObject user = (JSONObject) context.getRequest().getAttribute(User.USER);
final String userId = user.optString(Keys.OBJECT_ID);
final String url = requestJSONObject.optString(Common.URL);
FORGE_EXECUTOR_SERVICE.submit(new Runnable() {
@Override
public void run() {
linkForgeMgmtService.forge(url, userId);
}
});
}
/**
* Shows link forge.
*
* @param context the specified context
* @param request the specified request
* @param response the specified response
* @throws Exception exception
*/
@RequestProcessing(value = "/forge/link", method = HTTPRequestMethod.GET)
@Before(adviceClass = {StopwatchStartAdvice.class})
@After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class})
public void showLinkForge(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response)
throws Exception {
final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request);
context.setRenderer(renderer);
renderer.setTemplateName("other/link-forge.ftl");
final Map<String, Object> dataModel = renderer.getDataModel();
final List<JSONObject> tags = linkForgeQueryService.getForgedLinks();
dataModel.put(Tag.TAGS, (Object) tags);
dataModel.put(Common.SELECTED, Common.FORGE);
final JSONObject statistic = optionQueryService.getStatistic();
final int tagCnt = statistic.optInt(Option.ID_C_STATISTIC_TAG_COUNT);
dataModel.put(Tag.TAG_T_COUNT, tagCnt);
final int linkCnt = statistic.optInt(Option.ID_C_STATISTIC_LINK_COUNT);
dataModel.put(Link.LINK_T_COUNT, linkCnt);
dataModelService.fillHeaderAndFooter(request, response, dataModel);
}
/**
* Purges link forge.
*
* @param context the specified context
* @param request the specified request
* @param response the specified response
* @throws Exception exception
*/
@RequestProcessing(value = "/cron/forge/link/purge", method = HTTPRequestMethod.GET)
@Before(adviceClass = {StopwatchStartAdvice.class})
@After(adviceClass = {StopwatchEndAdvice.class})
public void purgeLinkForge(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response)
throws Exception {
final String key = Symphonys.get("keyOfSymphony");
if (!key.equals(request.getParameter("key"))) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
linkForgeMgmtService.purge();
context.renderJSON().renderTrueResult();
}
}