This commit is contained in:
Shinsuke Sugaya 2013-11-15 23:48:46 +09:00
parent 54689d0cf0
commit 27a4304092
19 changed files with 2142 additions and 1367 deletions

View file

@ -0,0 +1,44 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess;
public class WebApiException extends FessSystemException {
private static final long serialVersionUID = 1L;
private final int statusCode;
public int getStatusCode() {
return statusCode;
}
public WebApiException(final int statusCode, final String message,
final Throwable cause) {
super(message, cause);
this.statusCode = statusCode;
}
public WebApiException(final int statusCode, final String message) {
super(message);
this.statusCode = statusCode;
}
public WebApiException(final int statusCode, final Exception e) {
this(statusCode, e.getMessage(), e);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,87 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.api;
import jp.sf.fess.helper.LabelTypeHelper;
import jp.sf.fess.helper.QueryHelper;
import jp.sf.fess.suggest.SuggesterManager;
import org.codelibs.core.util.DynamicProperties;
import org.seasar.framework.container.SingletonS2Container;
public class BaseApiManager {
protected static final String FAVORITES_API = "/favoritesApi";
protected static final String FAVORITE_API = "/favoriteApi";
protected static final String HOT_SEARCH_WORD_API = "/hotSearchWordApi";
protected static final String ANALYSIS_API = "/analysisApi";
protected static final String SUGGEST_API = "/suggestApi";
protected static final String SEARCH_API = "/searchApi";
protected static enum FormatType {
SEARCH, LABEL, SUGGEST, ANALYSIS, HOTSEARCHWORD, FAVORITE, FAVORITES, OTHER;
}
public BaseApiManager() {
super();
}
protected FormatType getFormatType(final String formatType) {
if (formatType == null) {
return FormatType.SEARCH;
}
final String type = formatType.toUpperCase();
if (FormatType.SEARCH.name().equals(type)) {
return FormatType.SEARCH;
} else if (FormatType.LABEL.name().equals(type)) {
return FormatType.LABEL;
} else if (FormatType.SUGGEST.name().equals(type)) {
return FormatType.SUGGEST;
} else if (FormatType.ANALYSIS.name().equals(type)) {
return FormatType.ANALYSIS;
} else if (FormatType.HOTSEARCHWORD.name().equals(type)) {
return FormatType.HOTSEARCHWORD;
} else if (FormatType.FAVORITE.name().equals(type)) {
return FormatType.FAVORITE;
} else if (FormatType.FAVORITES.name().equals(type)) {
return FormatType.FAVORITES;
} else {
// default
return FormatType.OTHER;
}
}
protected DynamicProperties getCrawlerProperties() {
return SingletonS2Container.getComponent("crawlerProperties");
}
protected QueryHelper getQueryHelper() {
return SingletonS2Container.getComponent("queryHelper");
}
protected LabelTypeHelper getLabelTypeHelper() {
return SingletonS2Container.getComponent("labelTypeHelper");
}
protected SuggesterManager getSuggesterManager() {
return SingletonS2Container.getComponent("suggesterManager");
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.api;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface WebApiManager {
boolean matches(HttpServletRequest request);
void process(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException;
}

View file

@ -0,0 +1,46 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.api;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
public class WebApiManagerFactory {
protected WebApiManager[] webApiManagers = new WebApiManager[0];
public void add(final WebApiManager webApiManager) {
final List<WebApiManager> list = new ArrayList<WebApiManager>();
for (final WebApiManager manager : webApiManagers) {
list.add(manager);
}
list.add(webApiManager);
webApiManagers = list.toArray(new WebApiManager[list.size()]);
}
public WebApiManager get(final HttpServletRequest request) {
for (final WebApiManager webApiManager : webApiManagers) {
if (webApiManager.matches(request)) {
return webApiManager;
}
}
return null;
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.api;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class WebApiRequest extends HttpServletRequestWrapper {
protected String servletPath;
public WebApiRequest(final HttpServletRequest request,
final String servletPath) {
super(request);
this.servletPath = servletPath;
}
@Override
public String getServletPath() {
if (getQueryString() != null
&& getQueryString().indexOf("SAStruts.method") != -1) {
return super.getServletPath();
} else {
return servletPath;
}
}
}

View file

@ -0,0 +1,39 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.api;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.io.output.ByteArrayOutputStream;
public class WebApiResponse extends HttpServletResponseWrapper {
public WebApiResponse(final HttpServletResponse response) {
super(response);
}
@Override
public PrintWriter getWriter() throws IOException {
// dummy stream
return new PrintWriter(new ByteArrayOutputStream());
}
}

View file

@ -0,0 +1,800 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.api.json;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jp.sf.fess.Constants;
import jp.sf.fess.WebApiException;
import jp.sf.fess.api.BaseApiManager;
import jp.sf.fess.api.WebApiManager;
import jp.sf.fess.api.WebApiRequest;
import jp.sf.fess.api.WebApiResponse;
import jp.sf.fess.db.allcommon.CDef;
import jp.sf.fess.entity.FieldAnalysisResponse;
import jp.sf.fess.entity.SuggestResponse;
import jp.sf.fess.entity.SuggestResponse.SuggestResponseList;
import jp.sf.fess.suggest.Suggester;
import jp.sf.fess.util.FacetResponse;
import jp.sf.fess.util.FacetResponse.Field;
import jp.sf.fess.util.MoreLikeThisResponse;
import jp.sf.fess.util.WebApiUtil;
import org.seasar.framework.util.StringUtil;
import org.seasar.struts.util.RequestUtil;
import org.seasar.struts.util.ResponseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JsonApiManager extends BaseApiManager implements WebApiManager {
private static final Logger logger = LoggerFactory
.getLogger(JsonApiManager.class);
protected String jsonPathPrefix = "/json";
@Override
public boolean matches(final HttpServletRequest request) {
if (Constants.FALSE.equals(getCrawlerProperties().getProperty(
Constants.WEB_API_JSON_PROPERTY, Constants.TRUE))) {
return false;
}
final String servletPath = request.getServletPath();
return servletPath.startsWith(jsonPathPrefix);
}
@Override
public void process(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final String formatType = request.getParameter("type");
switch (getFormatType(formatType)) {
case SEARCH:
processSearchRequest(request, response, chain);
break;
case LABEL:
processLabelRequest(request, response, chain);
break;
case SUGGEST:
processSuggestRequest(request, response, chain);
break;
case ANALYSIS:
processAnalysisRequest(request, response, chain);
break;
case HOTSEARCHWORD:
processHotSearchWordRequest(request, response, chain);
break;
case FAVORITE:
processFavoriteRequest(request, response, chain);
break;
case FAVORITES:
processFavoritesRequest(request, response, chain);
break;
default:
writeJsonResponse(99, Constants.EMPTY_STRING, "Not found.");
break;
}
}
protected void processSearchRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
String query = null;
final StringBuilder buf = new StringBuilder(1000);
request.setAttribute(Constants.SEARCH_LOG_ACCESS_TYPE,
CDef.AccessType.Json);
final String queryId = request.getParameter("queryId");
try {
chain.doFilter(new WebApiRequest(request, SEARCH_API),
new WebApiResponse(response));
WebApiUtil.validate();
query = WebApiUtil.getObject("searchQuery");
final String execTime = WebApiUtil.getObject("execTime");
final String pageSize = WebApiUtil.getObject("pageSize");
final String currentPageNumber = WebApiUtil
.getObject("currentPageNumber");
final String allRecordCount = WebApiUtil
.getObject("allRecordCount");
final String allPageCount = WebApiUtil.getObject("allPageCount");
final List<Map<String, Object>> documentItems = WebApiUtil
.getObject("documentItems");
final FacetResponse facetResponse = WebApiUtil
.getObject("facetResponse");
final MoreLikeThisResponse moreLikeThisResponse = WebApiUtil
.getObject("moreLikeThisResponse");
buf.append("\"query\":\"");
buf.append(escapeJsonString(query));
buf.append("\",");
buf.append("\"execTime\":");
buf.append(execTime);
buf.append(',');
if (StringUtil.isNotBlank(queryId)) {
buf.append("\"queryId\":");
buf.append(escapeJsonString(queryId));
buf.append(',');
}
buf.append("\"pageSize\":");
buf.append(pageSize);
buf.append(',');
buf.append("\"pageNumber\":");
buf.append(currentPageNumber);
buf.append(',');
buf.append("\"recordCount\":");
buf.append(allRecordCount);
buf.append(',');
buf.append("\"pageCount\":");
buf.append(allPageCount);
if (!documentItems.isEmpty()) {
buf.append(',');
buf.append("\"result\":[");
boolean first1 = true;
for (final Map<String, Object> document : documentItems) {
if (!first1) {
buf.append(',');
} else {
first1 = false;
}
buf.append('{');
boolean first2 = true;
for (final Map.Entry<String, Object> entry : document
.entrySet()) {
final String name = entry.getKey();
if (StringUtil.isNotBlank(name)
&& entry.getValue() != null
&& getQueryHelper().isApiResponseField(name)) {
if (!first2) {
buf.append(',');
} else {
first2 = false;
}
buf.append('\"');
buf.append(escapeJsonString(name));
buf.append("\":\"");
buf.append(escapeJsonString(entry.getValue()
.toString()));
buf.append('\"');
}
}
buf.append('}');
}
buf.append(']');
}
if (facetResponse != null && facetResponse.hasFacetResponse()) {
// facet field
if (facetResponse.getFieldList() != null) {
buf.append(',');
buf.append("\"facetField\":[");
boolean first1 = true;
for (final Field field : facetResponse.getFieldList()) {
if (!first1) {
buf.append(',');
} else {
first1 = false;
}
buf.append("{\"name\":\"");
buf.append(escapeJsonString(field.getName()));
buf.append("\",\"result\":[");
boolean first2 = true;
for (final Map.Entry<String, Long> entry : field
.getValueCountMap().entrySet()) {
if (!first2) {
buf.append(',');
} else {
first2 = false;
}
buf.append("{\"value\":\"");
buf.append(escapeJsonString(entry.getKey()));
buf.append("\",\"count\":");
buf.append(entry.getValue());
buf.append('}');
}
buf.append(']');
buf.append('}');
}
buf.append(']');
}
// facet query
if (facetResponse.getQueryCountMap() != null) {
buf.append(',');
buf.append("\"facetQuery\":[");
boolean first1 = true;
for (final Map.Entry<String, Long> entry : facetResponse
.getQueryCountMap().entrySet()) {
if (!first1) {
buf.append(',');
} else {
first1 = false;
}
buf.append("{\"value\":\"");
buf.append(escapeJsonString(entry.getKey()));
buf.append("\",\"count\":");
buf.append(entry.getValue());
buf.append('}');
}
buf.append(']');
}
}
if (moreLikeThisResponse != null && !moreLikeThisResponse.isEmpty()) {
buf.append(',');
buf.append("\"moreLikeThis\":[");
boolean first = true;
for (final Map.Entry<String, List<Map<String, Object>>> mltEntry : moreLikeThisResponse
.entrySet()) {
if (!first) {
buf.append(',');
} else {
first = false;
}
buf.append("{\"id\":\"");
buf.append(escapeJsonString(mltEntry.getKey()));
buf.append("\",\"result\":[");
boolean first1 = true;
for (final Map<String, Object> document : mltEntry
.getValue()) {
if (!first1) {
buf.append(',');
} else {
first1 = false;
}
buf.append('{');
boolean first2 = true;
for (final Map.Entry<String, Object> entry : document
.entrySet()) {
if (StringUtil.isNotBlank(entry.getKey())
&& entry.getValue() != null) {
if (!first2) {
buf.append(',');
} else {
first2 = false;
}
buf.append('\"');
buf.append(escapeJsonString(entry.getKey()));
buf.append("\":\"");
buf.append(escapeJsonString(entry.getValue()
.toString()));
buf.append('\"');
}
}
buf.append('}');
}
buf.append("]}");
}
buf.append(']');
}
} catch (final Exception e) {
status = 1;
errMsg = e.getMessage();
if (errMsg == null) {
errMsg = e.getClass().getName();
}
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a search request.", e);
}
}
writeJsonResponse(status, buf.toString(), errMsg);
}
protected void processLabelRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
final StringBuilder buf = new StringBuilder(255);
try {
final List<Map<String, String>> labelTypeItems = getLabelTypeHelper()
.getLabelTypeItemList();
buf.append("\"recordCount\":");
buf.append(labelTypeItems.size());
if (!labelTypeItems.isEmpty()) {
buf.append(',');
buf.append("\"result\":[");
boolean first1 = true;
for (final Map<String, String> labelMap : labelTypeItems) {
if (!first1) {
buf.append(',');
} else {
first1 = false;
}
buf.append("{\"label\":\"");
buf.append(escapeJsonString(labelMap
.get(Constants.ITEM_LABEL)));
buf.append("\", \"value\":\"");
buf.append(escapeJsonString(labelMap
.get(Constants.ITEM_VALUE)));
buf.append("\"}");
}
buf.append(']');
}
} catch (final Exception e) {
status = 1;
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a label request.", e);
}
}
writeJsonResponse(status, buf.toString(), errMsg);
}
protected void processSuggestRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
final StringBuilder buf = new StringBuilder(255);
try {
chain.doFilter(new WebApiRequest(request, SUGGEST_API),
new WebApiResponse(response));
WebApiUtil.validate();
final Integer suggestRecordCount = WebApiUtil
.getObject("suggestRecordCount");
final List<SuggestResponse> suggestResultList = WebApiUtil
.getObject("suggestResultList");
final List<String> suggestFieldName = WebApiUtil
.getObject("suggestFieldName");
buf.append("\"recordCount\":");
buf.append(suggestRecordCount);
if (suggestResultList.size() > 0) {
buf.append(',');
buf.append("\"result\":[");
boolean first1 = true;
for (int i = 0; i < suggestResultList.size(); i++) {
final SuggestResponse suggestResponse = suggestResultList
.get(i);
for (final Map.Entry<String, List<String>> entry : suggestResponse
.entrySet()) {
final String fn = suggestFieldName.get(i);
final Suggester suggester = getSuggesterManager()
.getSuggester(fn);
if (suggester != null) {
if (!first1) {
buf.append(',');
} else {
first1 = false;
}
final SuggestResponseList srList = (SuggestResponseList) entry
.getValue();
buf.append("{\"token\":\"");
buf.append(escapeJsonString(entry.getKey()));
buf.append("\", \"fn\":\"");
buf.append(escapeJsonString(fn));
buf.append("\", \"startOffset\":");
buf.append(Integer.toString(srList.getStartOffset()));
buf.append(", \"endOffset\":");
buf.append(Integer.toString(srList.getEndOffset()));
buf.append(", \"numFound\":");
buf.append(Integer.toString(srList.getNumFound()));
buf.append(", ");
buf.append("\"result\":[");
boolean first2 = true;
for (final String value : srList) {
if (!first2) {
buf.append(',');
} else {
first2 = false;
}
buf.append('"');
buf.append(escapeJsonString(suggester
.convertResultString(value)));
buf.append('"');
}
buf.append("]}");
}
}
}
buf.append(']');
}
} catch (final Exception e) {
if (e instanceof WebApiException) {
status = ((WebApiException) e).getStatusCode();
} else {
status = 1;
}
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a suggest request.", e);
}
}
writeJsonResponse(status, buf.toString(), errMsg);
}
protected void processAnalysisRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
final StringBuilder buf = new StringBuilder(255);
try {
chain.doFilter(new WebApiRequest(request, ANALYSIS_API),
new WebApiResponse(response));
WebApiUtil.validate();
final FieldAnalysisResponse fieldAnalysis = WebApiUtil
.getObject("fieldAnalysis");
buf.append("\"recordCount\":");
buf.append(fieldAnalysis.size());
if (fieldAnalysis.size() > 0) {
buf.append(',');
buf.append("\"result\":[");
boolean first1 = true;
for (final Map.Entry<String, Map<String, List<Map<String, Object>>>> fEntry : fieldAnalysis
.entrySet()) {
if (first1) {
first1 = false;
} else {
buf.append(',');
}
buf.append("{\"field\":\"")
.append(escapeJsonString(fEntry.getKey()))
.append("\",\"analysis\":[");
boolean first2 = true;
for (final Map.Entry<String, List<Map<String, Object>>> aEntry : fEntry
.getValue().entrySet()) {
if (first2) {
first2 = false;
} else {
buf.append(',');
}
buf.append("{\"name\":\"")
.append(escapeJsonString(aEntry.getKey()))
.append("\",\"data\":[");
boolean first3 = true;
for (final Map<String, Object> dataMap : aEntry
.getValue()) {
if (first3) {
first3 = false;
} else {
buf.append(',');
}
buf.append('{');
boolean first4 = true;
for (final Map.Entry<String, Object> dEntry : dataMap
.entrySet()) {
final String key = dEntry.getKey();
final Object value = dEntry.getValue();
if (StringUtil.isNotBlank(key) && value != null) {
if (first4) {
first4 = false;
} else {
buf.append(',');
}
buf.append('\"')
.append(escapeJsonString(key))
.append("\":")
.append(escapeJson(value));
}
}
buf.append('}');
}
buf.append("]}");
}
buf.append("]}");
}
buf.append(']');
}
} catch (final Exception e) {
if (e instanceof WebApiException) {
status = ((WebApiException) e).getStatusCode();
} else {
status = 1;
}
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a suggest request.", e);
}
}
writeJsonResponse(status, buf.toString(), errMsg);
}
protected void processHotSearchWordRequest(
final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
final StringBuilder buf = new StringBuilder(255);
try {
chain.doFilter(new WebApiRequest(request, HOT_SEARCH_WORD_API),
new WebApiResponse(response));
WebApiUtil.validate();
final List<String> hotSearchWordList = WebApiUtil
.getObject("hotSearchWordList");
buf.append("\"result\":[");
boolean first1 = true;
for (final String word : hotSearchWordList) {
if (!first1) {
buf.append(',');
} else {
first1 = false;
}
buf.append("\"");
buf.append(escapeJsonString(word));
buf.append("\"");
}
buf.append(']');
} catch (final Exception e) {
if (e instanceof WebApiException) {
status = ((WebApiException) e).getStatusCode();
} else {
status = 1;
}
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a hotSearchWord request.", e);
}
}
writeJsonResponse(status, buf.toString(), errMsg);
}
protected void processFavoriteRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String body = null;
String errMsg = null;
try {
chain.doFilter(new WebApiRequest(request, FAVORITE_API),
new WebApiResponse(response));
WebApiUtil.validate();
body = "\"result\":\"ok\"";
} catch (final Exception e) {
if (e instanceof WebApiException) {
status = ((WebApiException) e).getStatusCode();
} else {
status = 1;
}
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a favorite request.", e);
}
}
writeJsonResponse(status, body, errMsg);
}
protected void processFavoritesRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String body = null;
String errMsg = null;
try {
chain.doFilter(new WebApiRequest(request, FAVORITES_API),
new WebApiResponse(response));
WebApiUtil.validate();
final List<String> docIdList = WebApiUtil.getObject("docIdList");
final StringBuilder buf = new StringBuilder();
buf.append("\"num\":").append(docIdList.size());
if (!docIdList.isEmpty()) {
buf.append(", \"docIds\":[");
for (int i = 0; i < docIdList.size(); i++) {
if (i > 0) {
buf.append(',');
}
buf.append('"');
buf.append(docIdList.get(i));
buf.append('"');
}
buf.append(']');
}
body = buf.toString();
} catch (final Exception e) {
if (e instanceof WebApiException) {
status = ((WebApiException) e).getStatusCode();
} else {
status = 1;
}
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a favorites request.", e);
}
}
writeJsonResponse(status, body, errMsg);
}
protected void writeJsonResponse(final int status, final String body,
final String errMsg) {
final String callback = RequestUtil.getRequest().getParameter(
"callback");
final boolean isJsonp = StringUtil.isNotBlank(callback);
final StringBuilder buf = new StringBuilder(1000);
if (isJsonp) {
buf.append(escapeCallbackName(callback));
buf.append('(');
}
buf.append("{\"response\":");
buf.append("{\"version\":");
buf.append(Constants.WEB_API_VERSION);
buf.append(',');
buf.append("\"status\":");
buf.append(status);
buf.append(',');
if (status == 0) {
buf.append(body);
} else {
buf.append("\"message\":\"");
buf.append(escapeJsonString(errMsg));
buf.append('\"');
}
buf.append('}');
buf.append('}');
if (isJsonp) {
buf.append(')');
}
ResponseUtil.write(buf.toString(), "text/javascript+json",
Constants.UTF_8);
}
protected String escapeCallbackName(final String callbackName) {
return callbackName.replaceAll("[^0-9a-zA-Z_\\$\\.]", "");
}
protected String escapeJson(final Object obj) {
final StringBuilder buf = new StringBuilder(255);
if (obj instanceof List<?>) {
buf.append('[');
boolean first = true;
for (final Object child : (List<?>) obj) {
if (first) {
first = false;
} else {
buf.append(',');
}
buf.append(escapeJson(child));
}
buf.append(']');
} else if (obj instanceof Map<?, ?>) {
buf.append('{');
boolean first = true;
for (final Map.Entry<?, ?> entry : ((Map<?, ?>) obj).entrySet()) {
if (first) {
first = false;
} else {
buf.append(',');
}
buf.append(escapeJson(entry.getKey())).append(':')
.append(escapeJson(entry.getValue()));
}
buf.append('}');
} else if (obj instanceof Integer || obj instanceof Long
|| obj instanceof Float || obj instanceof Double
|| obj instanceof Short) {
buf.append(obj);
} else if (obj == null) {
buf.append("\"\"");
} else {
buf.append('\"').append(escapeJsonString(obj.toString()))
.append('\"');
}
return buf.toString();
}
protected String escapeJsonString(final String str) {
if (str == null) {
return "";
}
final StringWriter out = new StringWriter(str.length() * 2);
int sz;
sz = str.length();
for (int i = 0; i < sz; i++) {
final char ch = str.charAt(i);
// handle unicode
if (ch > 0xfff) {
out.write("\\u" + hex(ch));
} else if (ch > 0xff) {
out.write("\\u0" + hex(ch));
} else if (ch > 0x7f) {
out.write("\\u00" + hex(ch));
} else if (ch < 32) {
switch (ch) {
case '\b':
out.write('\\');
out.write('b');
break;
case '\n':
out.write('\\');
out.write('n');
break;
case '\t':
out.write('\\');
out.write('t');
break;
case '\f':
out.write('\\');
out.write('f');
break;
case '\r':
out.write('\\');
out.write('r');
break;
default:
if (ch > 0xf) {
out.write("\\u00" + hex(ch));
} else {
out.write("\\u000" + hex(ch));
}
break;
}
} else {
switch (ch) {
case '"':
out.write("\\u0022");
break;
case '\\':
out.write("\\u005C");
break;
case '/':
out.write("\\u002F");
break;
default:
out.write(ch);
break;
}
}
}
return out.toString();
}
private String hex(final char ch) {
return Integer.toHexString(ch).toUpperCase();
}
public String getJsonPathPrefix() {
return jsonPathPrefix;
}
public void setJsonPathPrefix(final String jsonPathPrefix) {
this.jsonPathPrefix = jsonPathPrefix;
}
}

View file

@ -0,0 +1,494 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.api.xml;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jp.sf.fess.Constants;
import jp.sf.fess.WebApiException;
import jp.sf.fess.api.BaseApiManager;
import jp.sf.fess.api.WebApiManager;
import jp.sf.fess.api.WebApiRequest;
import jp.sf.fess.api.WebApiResponse;
import jp.sf.fess.db.allcommon.CDef;
import jp.sf.fess.entity.FieldAnalysisResponse;
import jp.sf.fess.entity.SuggestResponse;
import jp.sf.fess.entity.SuggestResponse.SuggestResponseList;
import jp.sf.fess.suggest.Suggester;
import jp.sf.fess.util.FacetResponse;
import jp.sf.fess.util.FacetResponse.Field;
import jp.sf.fess.util.MoreLikeThisResponse;
import jp.sf.fess.util.WebApiUtil;
import org.apache.commons.lang.StringEscapeUtils;
import org.seasar.framework.util.StringUtil;
import org.seasar.struts.util.ResponseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class XmlApiManager extends BaseApiManager implements WebApiManager {
private static final Logger logger = LoggerFactory
.getLogger(XmlApiManager.class);
protected String xmlPathPrefix = "/xml";
@Override
public boolean matches(final HttpServletRequest request) {
if (Constants.FALSE.equals(getCrawlerProperties().getProperty(
Constants.WEB_API_XML_PROPERTY, Constants.TRUE))) {
return false;
}
final String servletPath = request.getServletPath();
return servletPath.startsWith(xmlPathPrefix);
}
@Override
public void process(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final String formatType = request.getParameter("type");
switch (getFormatType(formatType)) {
case SEARCH:
processSearchRequest(request, response, chain);
break;
case LABEL:
processLabelRequest(request, response, chain);
break;
case SUGGEST:
processSuggestRequest(request, response, chain);
break;
case ANALYSIS:
processAnalysisRequest(request, response, chain);
break;
default:
writeXmlResponse(-1, Constants.EMPTY_STRING, "Not found.");
break;
}
}
protected void processSearchRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
final StringBuilder buf = new StringBuilder(1000);
String query = null;
request.setAttribute(Constants.SEARCH_LOG_ACCESS_TYPE,
CDef.AccessType.Xml);
final String queryId = request.getParameter("queryId");
try {
chain.doFilter(new WebApiRequest(request, SEARCH_API),
new WebApiResponse(response));
WebApiUtil.validate();
query = WebApiUtil.getObject("searchQuery");
final String execTime = WebApiUtil.getObject("execTime");
final String pageSize = WebApiUtil.getObject("pageSize");
final String currentPageNumber = WebApiUtil
.getObject("currentPageNumber");
final String allRecordCount = WebApiUtil
.getObject("allRecordCount");
final String allPageCount = WebApiUtil.getObject("allPageCount");
final List<Map<String, Object>> documentItems = WebApiUtil
.getObject("documentItems");
final FacetResponse facetResponse = WebApiUtil
.getObject("facetResponse");
final MoreLikeThisResponse moreLikeThisResponse = WebApiUtil
.getObject("moreLikeThisResponse");
buf.append("<query>");
buf.append(StringEscapeUtils.escapeXml(query));
buf.append("</query>");
buf.append("<exec-time>");
buf.append(execTime);
buf.append("</exec-time>");
if (StringUtil.isNotBlank(queryId)) {
buf.append("<query-id>");
buf.append(StringEscapeUtils.escapeXml(queryId));
buf.append("</query-id>");
}
buf.append("<page-size>");
buf.append(pageSize);
buf.append("</page-size>");
buf.append("<page-number>");
buf.append(currentPageNumber);
buf.append("</page-number>");
buf.append("<record-count>");
buf.append(allRecordCount);
buf.append("</record-count>");
buf.append("<page-count>");
buf.append(allPageCount);
buf.append("</page-count>");
buf.append("<result>");
for (final Map<String, Object> document : documentItems) {
buf.append("<doc>");
for (final Map.Entry<String, Object> entry : document
.entrySet()) {
final String name = entry.getKey();
if (StringUtil.isNotBlank(name) && entry.getValue() != null
&& getQueryHelper().isApiResponseField(name)) {
final String tagName = StringUtil.decamelize(name)
.replaceAll("_", "-").toLowerCase();
buf.append('<');
buf.append(tagName);
buf.append('>');
buf.append(StringEscapeUtils.escapeXml(entry.getValue()
.toString()));
buf.append("</");
buf.append(tagName);
buf.append('>');
}
}
buf.append("</doc>");
}
buf.append("</result>");
if (facetResponse != null && facetResponse.hasFacetResponse()) {
buf.append("<facet>");
// facet field
if (facetResponse.getFieldList() != null) {
for (final Field field : facetResponse.getFieldList()) {
buf.append("<field name=\"");
buf.append(StringEscapeUtils.escapeXml(field.getName()));
buf.append("\">");
for (final Map.Entry<String, Long> entry : field
.getValueCountMap().entrySet()) {
buf.append("<value count=\"");
buf.append(entry.getValue());
buf.append("\">");
buf.append(StringEscapeUtils.escapeXml(entry
.getKey()));
buf.append("</value>");
}
buf.append("</field>");
}
}
// facet query
if (facetResponse.getQueryCountMap() != null) {
buf.append("<query>");
for (final Map.Entry<String, Long> entry : facetResponse
.getQueryCountMap().entrySet()) {
buf.append("<value count=\"");
buf.append(entry.getValue());
buf.append("\">");
buf.append(StringEscapeUtils.escapeXml(entry.getKey()));
buf.append("</value>");
}
buf.append("</query>");
}
buf.append("</facet>");
}
if (moreLikeThisResponse != null && !moreLikeThisResponse.isEmpty()) {
buf.append("<more-like-this>");
for (final Map.Entry<String, List<Map<String, Object>>> mltEntry : moreLikeThisResponse
.entrySet()) {
buf.append("<result id=\"");
buf.append(StringEscapeUtils.escapeXml(mltEntry.getKey()));
buf.append("\">");
for (final Map<String, Object> document : mltEntry
.getValue()) {
buf.append("<doc>");
for (final Map.Entry<String, Object> entry : document
.entrySet()) {
if (StringUtil.isNotBlank(entry.getKey())
&& entry.getValue() != null) {
final String tagName = StringUtil
.decamelize(entry.getKey())
.replaceAll("_", "-").toLowerCase();
buf.append('<');
buf.append(tagName);
buf.append('>');
buf.append(StringEscapeUtils.escapeXml(entry
.getValue().toString()));
buf.append("</");
buf.append(tagName);
buf.append('>');
}
}
buf.append("</doc>");
}
buf.append("</result>");
}
buf.append("</more-like-this>");
}
} catch (final Exception e) {
status = 1;
errMsg = e.getMessage();
if (errMsg == null) {
errMsg = e.getClass().getName();
}
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a search request.", e);
}
}
writeXmlResponse(status, buf.toString(), errMsg);
}
protected void processLabelRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
final StringBuilder buf = new StringBuilder(255);
try {
final List<Map<String, String>> labelTypeItems = getLabelTypeHelper()
.getLabelTypeItemList();
buf.append("<record-count>");
buf.append(labelTypeItems.size());
buf.append("</record-count>");
buf.append("<result>");
for (final Map<String, String> labelMap : labelTypeItems) {
buf.append("<label>");
buf.append("<name>");
buf.append(StringEscapeUtils.escapeXml(labelMap
.get(Constants.ITEM_LABEL)));
buf.append("</name>");
buf.append("<value>");
buf.append(StringEscapeUtils.escapeXml(labelMap
.get(Constants.ITEM_VALUE)));
buf.append("</value>");
buf.append("</label>");
}
buf.append("</result>");
} catch (final Exception e) {
status = 1;
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a label request.", e);
}
}
writeXmlResponse(status, buf.toString(), errMsg);
}
protected void processSuggestRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
final StringBuilder buf = new StringBuilder(255);
try {
chain.doFilter(new WebApiRequest(request, SUGGEST_API),
new WebApiResponse(response));
WebApiUtil.validate();
final Integer suggestRecordCount = WebApiUtil
.getObject("suggestRecordCount");
final List<SuggestResponse> suggestResultList = WebApiUtil
.getObject("suggestResultList");
final List<String> suggestFieldName = WebApiUtil
.getObject("suggestFieldName");
buf.append("<record-count>");
buf.append(suggestRecordCount);
buf.append("</record-count>");
if (suggestResultList.size() > 0) {
buf.append("<result>");
for (int i = 0; i < suggestResultList.size(); i++) {
final SuggestResponse suggestResponse = suggestResultList
.get(i);
for (final Map.Entry<String, List<String>> entry : suggestResponse
.entrySet()) {
final SuggestResponseList srList = (SuggestResponseList) entry
.getValue();
final String fn = suggestFieldName.get(i);
final Suggester suggester = getSuggesterManager()
.getSuggester(fn);
if (suggester != null) {
buf.append("<suggest>");
buf.append("<token>");
buf.append(StringEscapeUtils.escapeXml(entry
.getKey()));
buf.append("</token>");
buf.append("<fn>");
buf.append(StringEscapeUtils.escapeXml(fn));
buf.append("</fn>");
buf.append("<start-offset>");
buf.append(StringEscapeUtils.escapeXml(Integer
.toString(srList.getStartOffset())));
buf.append("</start-offset>");
buf.append("<end-offset>");
buf.append(StringEscapeUtils.escapeXml(Integer
.toString(srList.getEndOffset())));
buf.append("</end-offset>");
buf.append("<num-found>");
buf.append(StringEscapeUtils.escapeXml(Integer
.toString(srList.getNumFound())));
buf.append("</num-found>");
buf.append("<result>");
for (final String value : srList) {
buf.append("<value>");
buf.append(StringEscapeUtils
.escapeXml(suggester
.convertResultString(value)));
buf.append("</value>");
}
buf.append("</result>");
buf.append("</suggest>");
}
}
}
buf.append("</result>");
}
} catch (final Exception e) {
if (e instanceof WebApiException) {
status = ((WebApiException) e).getStatusCode();
} else {
status = 1;
}
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a suggest request.", e);
}
}
writeXmlResponse(status, buf.toString(), errMsg);
}
protected String processAnalysisRequest(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain) {
int status = 0;
String errMsg = Constants.EMPTY_STRING;
final StringBuilder buf = new StringBuilder(255);
try {
chain.doFilter(new WebApiRequest(request, ANALYSIS_API),
new WebApiResponse(response));
WebApiUtil.validate();
final FieldAnalysisResponse fieldAnalysis = WebApiUtil
.getObject("fieldAnalysis");
buf.append("<record-count>");
buf.append(fieldAnalysis.size());
buf.append("</record-count>");
if (fieldAnalysis.size() > 0) {
buf.append("<result>");
for (final Map.Entry<String, Map<String, List<Map<String, Object>>>> fEntry : fieldAnalysis
.entrySet()) {
buf.append("<field name=\"")
.append(StringEscapeUtils.escapeXml(fEntry.getKey()))
.append("\">");
for (final Map.Entry<String, List<Map<String, Object>>> aEntry : fEntry
.getValue().entrySet()) {
buf.append("<analysis name=\"")
.append(StringEscapeUtils.escapeXml(aEntry
.getKey())).append("\">");
for (final Map<String, Object> dataMap : aEntry
.getValue()) {
buf.append("<token>");
for (final Map.Entry<String, Object> dEntry : dataMap
.entrySet()) {
final String key = dEntry.getKey();
final Object value = dEntry.getValue();
if (StringUtil.isNotBlank(key) && value != null) {
buf.append("<value name=\"")
.append(StringEscapeUtils
.escapeXml(key))
.append("\">")
.append(escapeXml(value))
.append("</value>");
}
}
buf.append("</token>");
}
buf.append("</analysis>");
}
buf.append("</field>");
}
buf.append("</result>");
}
} catch (final Exception e) {
if (e instanceof WebApiException) {
status = ((WebApiException) e).getStatusCode();
} else {
status = 1;
}
errMsg = e.getMessage();
if (logger.isDebugEnabled()) {
logger.debug("Failed to process a suggest request.", e);
}
}
writeXmlResponse(status, buf.toString(), errMsg);
return null;
}
protected void writeXmlResponse(final int status, final String body,
final String errMsg) {
final StringBuilder buf = new StringBuilder(1000);
buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buf.append("<response>");
buf.append("<version>");
buf.append(Constants.WEB_API_VERSION);
buf.append("</version>");
buf.append("<status>");
buf.append(status);
buf.append("</status>");
if (status == 0) {
buf.append(body);
} else {
buf.append("<message>");
buf.append(StringEscapeUtils.escapeXml(errMsg));
buf.append("</message>");
}
buf.append("</response>");
ResponseUtil.write(buf.toString(), "text/xml", Constants.UTF_8);
}
protected String escapeXml(final Object obj) {
final StringBuilder buf = new StringBuilder(255);
if (obj instanceof List<?>) {
buf.append("<list>");
for (final Object child : (List<?>) obj) {
buf.append("<item>").append(escapeXml(child)).append("</item>");
}
buf.append("</list>");
} else if (obj instanceof Map<?, ?>) {
buf.append("<data>");
for (final Map.Entry<?, ?> entry : ((Map<?, ?>) obj).entrySet()) {
buf.append("<name>").append(escapeXml(entry.getKey()))
.append("</name><value>")
.append(escapeXml(entry.getValue())).append("</value>");
}
buf.append("</data>");
} else if (obj != null) {
buf.append(StringEscapeUtils.escapeXml(obj.toString()));
}
return buf.toString();
}
public String getXmlPathPrefix() {
return xmlPathPrefix;
}
public void setXmlPathPrefix(final String xmlPathPrefix) {
this.xmlPathPrefix = xmlPathPrefix;
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jp.sf.fess.api.WebApiManager;
import jp.sf.fess.api.WebApiManagerFactory;
import org.seasar.framework.container.SingletonS2Container;
public class WebApiFilter implements Filter {
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(final ServletRequest request,
final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final WebApiManagerFactory webApiManagerFactory = SingletonS2Container
.getComponent(WebApiManagerFactory.class);
final WebApiManager webApiManager = webApiManagerFactory
.get((HttpServletRequest) request);
if (webApiManager == null) {
chain.doFilter(request, response);
} else {
webApiManager.process((HttpServletRequest) request,
(HttpServletResponse) response, chain);
}
}
}

View file

@ -34,6 +34,7 @@ import jp.sf.fess.db.exbhv.pmbean.HotSearchWordPmb;
import org.seasar.dbflute.jdbc.CursorHandler;
import org.seasar.framework.container.annotation.tiger.InitMethod;
import org.seasar.framework.util.StringUtil;
public class HotSearchWordHelper {
@ -77,6 +78,9 @@ public class HotSearchWordHelper {
throws SQLException {
while (rs.next()) {
final String word = rs.getString("name");
if (StringUtil.isBlank(word)) {
continue;
}
if (excludedWordPattern != null) {
if (!excludedWordPattern.matcher(word)
.matches()) {

View file

@ -1,3 +1,19 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.helper;
import javax.servlet.http.HttpServletRequest;

View file

@ -0,0 +1,58 @@
/*
* Copyright 2009-2013 the Fess Project and the Others.
*
* 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 jp.sf.fess.util;
import jp.sf.fess.WebApiException;
import org.seasar.struts.util.RequestUtil;
public class WebApiUtil {
private static final String WEB_API_EXCEPTION = "webApiException";
private WebApiUtil() {
}
public static void setObject(final String name, final Object value) {
RequestUtil.getRequest().setAttribute(name, value);
}
public static <T> T getObject(final String name) {
@SuppressWarnings("unchecked")
final T value = (T) RequestUtil.getRequest().getAttribute(name);
return value;
}
public static void setError(final int statusCode, final String message) {
RequestUtil.getRequest().setAttribute(WEB_API_EXCEPTION,
new WebApiException(statusCode, message));
}
public static void setError(final int statusCode, final Exception e) {
RequestUtil.getRequest().setAttribute(WEB_API_EXCEPTION,
new WebApiException(statusCode, e));
}
public static void validate() {
final WebApiException e = (WebApiException) RequestUtil.getRequest()
.getAttribute(WEB_API_EXCEPTION);
if (e != null) {
throw e;
}
}
}

View file

@ -71,6 +71,11 @@
</init-param>
</filter>
<filter>
<filter-name>webApiFilter</filter-name>
<filter-class>jp.sf.fess.filter.WebApiFilter</filter-class>
</filter>
<filter>
<filter-name>routingfilter</filter-name>
<filter-class>org.seasar.struts.filter.RoutingFilter</filter-class>
@ -114,6 +119,12 @@
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>webApiFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>routingfilter</filter-name>
<url-pattern>/*</url-pattern>
@ -237,6 +248,10 @@
</security-role>
-->
<error-page>
<error-code>400</error-code>
<location>/WEB-INF/view/error/redirect.jsp?type=badRequest</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/WEB-INF/view/error/redirect.jsp?type=logOut</location>

View file

@ -71,6 +71,11 @@
</init-param>
</filter>
<filter>
<filter-name>webApiFilter</filter-name>
<filter-class>jp.sf.fess.filter.WebApiFilter</filter-class>
</filter>
<filter>
<filter-name>routingfilter</filter-name>
<filter-class>org.seasar.struts.filter.RoutingFilter</filter-class>
@ -114,6 +119,12 @@
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>webApiFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>routingfilter</filter-name>
<url-pattern>/*</url-pattern>
@ -237,6 +248,10 @@
</security-role>
-->
<error-page>
<error-code>400</error-code>
<location>/WEB-INF/view/error/redirect.jsp?type=badRequest</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/WEB-INF/view/error/redirect.jsp?type=logOut</location>

View file

@ -4,6 +4,7 @@
<components>
<include path="solrlib.dicon"/>
<include path="fess_ds.dicon"/>
<include path="fess_api.dicon"/>
<component name="crawlerProperties" class="org.codelibs.core.util.DynamicProperties">
<arg>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<component name="webApiManagerFactory" class="jp.sf.fess.api.WebApiManagerFactory">
<initMethod name="add">
<arg>xmlApiManager</arg>
</initMethod>
<initMethod name="add">
<arg>jsonApiManager</arg>
</initMethod>
</component>
<component name="xmlApiManager" class="jp.sf.fess.api.xml.XmlApiManager">
</component>
<component name="jsonApiManager" class="jp.sf.fess.api.json.JsonApiManager">
</component>
</components>

View file

@ -71,6 +71,11 @@
</init-param>
</filter>
<filter>
<filter-name>webApiFilter</filter-name>
<filter-class>jp.sf.fess.filter.WebApiFilter</filter-class>
</filter>
<filter>
<filter-name>routingfilter</filter-name>
<filter-class>org.seasar.struts.filter.RoutingFilter</filter-class>
@ -114,6 +119,12 @@
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>webApiFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>routingfilter</filter-name>
<url-pattern>/*</url-pattern>

View file

@ -58,7 +58,7 @@ $(function(){
var values = $favorite.attr('href').split('#');
if(values.length === 2 && $queryId.size() > 0){
var contextPath = $('#contextPath').val();
var actionUrl = contextPath + '/favorite';
var actionUrl = contextPath + '/json';
var docId = values[1];
$.ajax({
dataType: 'json',
@ -67,6 +67,7 @@ $(function(){
timeoutNumber: 10000,
url: actionUrl,
data: {
type: 'favorite',
docId: docId,
queryId: $queryId.val()
}
@ -93,8 +94,9 @@ $(function(){
cache: false,
type: 'post',
timeoutNumber: 10000,
url: contextPath + '/favorites',
url: contextPath + '/json',
data: {
type: 'favorites',
queryId: $queryId.val()
}
}).done(function ( data ) {