|
@@ -0,0 +1,670 @@
|
|
|
+/*
|
|
|
+ * Copyright 2009-2015 the CodeLibs 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.net.URLDecoder;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Map.Entry;
|
|
|
+
|
|
|
+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.PingResponse;
|
|
|
+import jp.sf.fess.entity.PingResponse.Target;
|
|
|
+import jp.sf.fess.service.SearchService;
|
|
|
+import jp.sf.fess.suggest.entity.SpellCheckResponse;
|
|
|
+import jp.sf.fess.suggest.entity.SuggestResponse;
|
|
|
+import jp.sf.fess.suggest.entity.SuggestResponse.SuggestResponseList;
|
|
|
+import jp.sf.fess.util.ComponentUtil;
|
|
|
+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.codelibs.core.CoreLibConstants;
|
|
|
+import org.codelibs.core.util.StringUtil;
|
|
|
+import org.seasar.struts.util.ResponseUtil;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+public class GsaApiManager extends BaseApiManager implements WebApiManager {
|
|
|
+ private static final Logger logger = LoggerFactory
|
|
|
+ .getLogger(GsaApiManager.class);
|
|
|
+
|
|
|
+ protected String gsaPathPrefix = "/gsa";
|
|
|
+
|
|
|
+ private static final String GSA_META_PREFIX = "MT_";
|
|
|
+
|
|
|
+ private static final String GSA_META_SUFFIX = "_s";
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean matches(final HttpServletRequest request) {
|
|
|
+ if (Constants.FALSE.equals(ComponentUtil.getCrawlerProperties()
|
|
|
+ .getProperty(Constants.WEB_API_XML_PROPERTY, Constants.TRUE))) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ final String servletPath = request.getServletPath();
|
|
|
+ return servletPath.startsWith(gsaPathPrefix);
|
|
|
+ }
|
|
|
+
|
|
|
+ @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 SPELLCHECK:
|
|
|
+ processSpellCheckRequest(request, response, chain);
|
|
|
+ break;
|
|
|
+ case ANALYSIS:
|
|
|
+ processAnalysisRequest(request, response, chain);
|
|
|
+ break;
|
|
|
+ case PING:
|
|
|
+ processPingRequest(request, response, chain);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ writeXmlResponse(-1, StringUtil.EMPTY, "Not found.");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void processPingRequest(final HttpServletRequest request,
|
|
|
+ final HttpServletResponse response, final FilterChain chain) {
|
|
|
+ final SearchService searchService = ComponentUtil.getSearchService();
|
|
|
+ int status;
|
|
|
+ final StringBuilder buf = new StringBuilder(1000);
|
|
|
+ String errMsg = null;
|
|
|
+ try {
|
|
|
+ final PingResponse pingResponse = searchService.ping();
|
|
|
+ status = pingResponse.getStatus();
|
|
|
+ buf.append("<result>");
|
|
|
+ for (final Target target : pingResponse.getTargets()) {
|
|
|
+ buf.append("<server><status>");
|
|
|
+ buf.append(target.getStatus());
|
|
|
+ buf.append("</status><url>");
|
|
|
+ buf.append(escapeXml(target.getUrl()));
|
|
|
+ buf.append("</url><query-time>");
|
|
|
+ buf.append(target.getQueryTime());
|
|
|
+ buf.append("</query-time><search-time>");
|
|
|
+ buf.append(target.getSearchTime());
|
|
|
+ buf.append("</search-time></server>");
|
|
|
+ }
|
|
|
+ buf.append("</result>");
|
|
|
+ } catch (final Exception e) {
|
|
|
+ status = 9;
|
|
|
+ errMsg = e.getMessage();
|
|
|
+ if (errMsg == null) {
|
|
|
+ errMsg = e.getClass().getName();
|
|
|
+ }
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.debug("Failed to process a ping request.", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ writeXmlResponse(status, buf.toString(), errMsg);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void processSearchRequest(final HttpServletRequest request,
|
|
|
+ final HttpServletResponse response, final FilterChain chain) {
|
|
|
+ int status = 0;
|
|
|
+ String errMsg = StringUtil.EMPTY;
|
|
|
+ final StringBuilder buf = new StringBuilder(1000);
|
|
|
+ String query = null;
|
|
|
+ request.setAttribute(Constants.SEARCH_LOG_ACCESS_TYPE,
|
|
|
+ CDef.AccessType.Xml);
|
|
|
+ try {
|
|
|
+ chain.doFilter(new WebApiRequest(request, GSA_SEARCH_API),
|
|
|
+ new WebApiResponse(response));
|
|
|
+ WebApiUtil.validate();
|
|
|
+ query = WebApiUtil.getObject("searchQueryOriginal");
|
|
|
+ final String execTime = WebApiUtil.getObject("execTime");
|
|
|
+ final int pageSize = Integer.parseInt((String) WebApiUtil.getObject("pageSize"));
|
|
|
+ final int allRecordCount = Integer.parseInt((String) WebApiUtil
|
|
|
+ .getObject("allRecordCount"));
|
|
|
+ final List<Map<String, Object>> documentItems = WebApiUtil
|
|
|
+ .getObject("documentItems");
|
|
|
+ final String start = request.getParameter("start");
|
|
|
+ int startNumber = 1;
|
|
|
+ if (StringUtil.isNotBlank(start)) {
|
|
|
+ startNumber = Integer.parseInt(start) + 1;
|
|
|
+ }
|
|
|
+ int endNumber = startNumber + pageSize -1;
|
|
|
+ if (endNumber > allRecordCount) {
|
|
|
+ endNumber = allRecordCount;
|
|
|
+ }
|
|
|
+ final FacetResponse facetResponse = WebApiUtil
|
|
|
+ .getObject("facetResponse");
|
|
|
+ final MoreLikeThisResponse moreLikeThisResponse = WebApiUtil
|
|
|
+ .getObject("moreLikeThisResponse");
|
|
|
+ List<String> getFields = WebApiUtil.getObject("getFields");
|
|
|
+
|
|
|
+ buf.append("<Q>");
|
|
|
+ buf.append(escapeXml(query));
|
|
|
+ buf.append("</Q>");
|
|
|
+ buf.append("<TM>");
|
|
|
+ buf.append(execTime);
|
|
|
+ buf.append("</TM>");
|
|
|
+ for (final Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
|
|
+ final String[] values = entry.getValue();
|
|
|
+ if (values == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ final String key = entry.getKey();
|
|
|
+ for (final String value : values) {
|
|
|
+ buf.append("<PARAM name=\"");
|
|
|
+ buf.append(key);
|
|
|
+ buf.append("\" value=\"");
|
|
|
+ buf.append(value);
|
|
|
+ buf.append("\" original_value=\"");
|
|
|
+ // TODO: should be saved original input value
|
|
|
+ buf.append(URLEncoder.encode(value, Constants.UTF_8));
|
|
|
+ buf.append("\"/>");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ buf.append("<M>");
|
|
|
+ buf.append(allRecordCount);
|
|
|
+ buf.append("</M>");
|
|
|
+ if (documentItems.size() > 0) {
|
|
|
+ buf.append("<RES SN=\"");
|
|
|
+ buf.append(startNumber);
|
|
|
+ buf.append("\" EN=\"");
|
|
|
+ buf.append(endNumber);
|
|
|
+ buf.append("\">");
|
|
|
+ int recordNumber = startNumber;
|
|
|
+ for (Map<String, Object> document : documentItems) {
|
|
|
+ buf.append("<R N=\"");
|
|
|
+ buf.append(recordNumber);
|
|
|
+ buf.append("\">");
|
|
|
+ final String url = (String) document.remove("url");
|
|
|
+ document.put("UE", url);
|
|
|
+ document.put("U", URLDecoder.decode(url, Constants.UTF_8));
|
|
|
+ document.put("T", document.remove("title"));
|
|
|
+ document.put("RK", document.remove("sore"));
|
|
|
+ document.put("S", ((String) document
|
|
|
+ .remove("contentDescription")).replaceAll(
|
|
|
+ "<(/*)em>", "<$1b>"));
|
|
|
+ for (final Map.Entry<String, Object> entry : document
|
|
|
+ .entrySet()) {
|
|
|
+ final String name = entry.getKey();
|
|
|
+ if (StringUtil.isNotBlank(name)
|
|
|
+ && entry.getValue() != null
|
|
|
+ && ComponentUtil.getQueryHelper()
|
|
|
+ .isApiResponseField(name)) {
|
|
|
+ if (name.startsWith(GSA_META_PREFIX)) {
|
|
|
+ final String tagName = name.replaceAll(
|
|
|
+ "^" + GSA_META_PREFIX, "").replaceAll(
|
|
|
+ GSA_META_SUFFIX + "\\z", "");
|
|
|
+ if (getFields.contains(tagName)) {
|
|
|
+ buf.append("<MT N=\"");
|
|
|
+ buf.append(tagName);
|
|
|
+ buf.append("\" V=\"");
|
|
|
+ buf.append(escapeXml(entry.getValue()
|
|
|
+ .toString()));
|
|
|
+ buf.append("\"/>");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ final String tagName = name;
|
|
|
+ buf.append('<');
|
|
|
+ buf.append(tagName);
|
|
|
+ buf.append('>');
|
|
|
+ buf.append(escapeXml(entry.getValue()));
|
|
|
+ buf.append("</");
|
|
|
+ buf.append(tagName);
|
|
|
+ buf.append('>');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ buf.append("</R>");
|
|
|
+ recordNumber++;
|
|
|
+ }
|
|
|
+ buf.append("</RES>");
|
|
|
+ } else {
|
|
|
+ buf.append("<RES/>");
|
|
|
+ }
|
|
|
+ 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(escapeXml(field.getName()));
|
|
|
+ buf.append("\">");
|
|
|
+ for (final Map.Entry<String, Long> entry : field
|
|
|
+ .getValueCountMap().entrySet()) {
|
|
|
+ buf.append("<value count=\"");
|
|
|
+ buf.append(escapeXml(entry.getValue()));
|
|
|
+ buf.append("\">");
|
|
|
+ buf.append(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(escapeXml(entry.getValue()));
|
|
|
+ buf.append("\">");
|
|
|
+ buf.append(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(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 = convertTagName(entry
|
|
|
+ .getKey());
|
|
|
+ buf.append('<');
|
|
|
+ buf.append(tagName);
|
|
|
+ buf.append('>');
|
|
|
+ buf.append(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);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String convertTagName(final String name) {
|
|
|
+ final String tagName = StringUtil.decamelize(name).replaceAll("_", "-")
|
|
|
+ .toLowerCase();
|
|
|
+ return tagName;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void processLabelRequest(final HttpServletRequest request,
|
|
|
+ final HttpServletResponse response, final FilterChain chain) {
|
|
|
+ int status = 0;
|
|
|
+ String errMsg = StringUtil.EMPTY;
|
|
|
+ final StringBuilder buf = new StringBuilder(255);
|
|
|
+ try {
|
|
|
+ final List<Map<String, String>> labelTypeItems = ComponentUtil
|
|
|
+ .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(escapeXml(labelMap.get(Constants.ITEM_LABEL)));
|
|
|
+ buf.append("</name>");
|
|
|
+ buf.append("<value>");
|
|
|
+ buf.append(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 = StringUtil.EMPTY;
|
|
|
+ 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);
|
|
|
+ buf.append("<suggest>");
|
|
|
+ buf.append("<token>");
|
|
|
+ buf.append(escapeXml(entry.getKey()));
|
|
|
+ buf.append("</token>");
|
|
|
+ buf.append("<fn>");
|
|
|
+ buf.append(escapeXml(fn));
|
|
|
+ buf.append("</fn>");
|
|
|
+ buf.append("<start-offset>");
|
|
|
+ buf.append(escapeXml(Integer.toString(srList
|
|
|
+ .getStartOffset())));
|
|
|
+ buf.append("</start-offset>");
|
|
|
+ buf.append("<end-offset>");
|
|
|
+ buf.append(escapeXml(Integer.toString(srList
|
|
|
+ .getEndOffset())));
|
|
|
+ buf.append("</end-offset>");
|
|
|
+ buf.append("<num-found>");
|
|
|
+ buf.append(escapeXml(Integer.toString(srList
|
|
|
+ .getNumFound())));
|
|
|
+ buf.append("</num-found>");
|
|
|
+ buf.append("<result>");
|
|
|
+ for (final String value : srList) {
|
|
|
+ buf.append("<value>");
|
|
|
+ buf.append(escapeXml(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 void processSpellCheckRequest(final HttpServletRequest request,
|
|
|
+ final HttpServletResponse response, final FilterChain chain) {
|
|
|
+
|
|
|
+ int status = 0;
|
|
|
+ String errMsg = StringUtil.EMPTY;
|
|
|
+ final StringBuilder buf = new StringBuilder(255);
|
|
|
+ try {
|
|
|
+ chain.doFilter(new WebApiRequest(request, SPELLCHECK_API),
|
|
|
+ new WebApiResponse(response));
|
|
|
+ WebApiUtil.validate();
|
|
|
+ final Integer spellCheckRecordCount = WebApiUtil
|
|
|
+ .getObject("spellCheckRecordCount");
|
|
|
+ final List<SpellCheckResponse> spellCheckResultList = WebApiUtil
|
|
|
+ .getObject("spellCheckResultList");
|
|
|
+ final List<String> spellCheckFieldName = WebApiUtil
|
|
|
+ .getObject("spellCheckFieldName");
|
|
|
+
|
|
|
+ buf.append("<record-count>");
|
|
|
+ buf.append(spellCheckRecordCount);
|
|
|
+ buf.append("</record-count>");
|
|
|
+ if (spellCheckResultList.size() > 0) {
|
|
|
+ buf.append("<result>");
|
|
|
+
|
|
|
+ for (int i = 0; i < spellCheckResultList.size(); i++) {
|
|
|
+
|
|
|
+ final SuggestResponse suggestResponse = spellCheckResultList
|
|
|
+ .get(i);
|
|
|
+
|
|
|
+ for (final Map.Entry<String, List<String>> entry : suggestResponse
|
|
|
+ .entrySet()) {
|
|
|
+ final SuggestResponseList srList = (SuggestResponseList) entry
|
|
|
+ .getValue();
|
|
|
+ final String fn = spellCheckFieldName.get(i);
|
|
|
+ buf.append("<suggest>");
|
|
|
+ buf.append("<token>");
|
|
|
+ buf.append(escapeXml(entry.getKey()));
|
|
|
+ buf.append("</token>");
|
|
|
+ buf.append("<fn>");
|
|
|
+ buf.append(escapeXml(fn));
|
|
|
+ buf.append("</fn>");
|
|
|
+ buf.append("<start-offset>");
|
|
|
+ buf.append(escapeXml(Integer.toString(srList
|
|
|
+ .getStartOffset())));
|
|
|
+ buf.append("</start-offset>");
|
|
|
+ buf.append("<end-offset>");
|
|
|
+ buf.append(escapeXml(Integer.toString(srList
|
|
|
+ .getEndOffset())));
|
|
|
+ buf.append("</end-offset>");
|
|
|
+ buf.append("<num-found>");
|
|
|
+ buf.append(escapeXml(Integer.toString(srList
|
|
|
+ .getNumFound())));
|
|
|
+ buf.append("</num-found>");
|
|
|
+ buf.append("<result>");
|
|
|
+ for (final String value : srList) {
|
|
|
+ buf.append("<value>");
|
|
|
+ buf.append(escapeXml(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 spellcheck request.", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ writeXmlResponse(status, buf.toString(), errMsg);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected String processAnalysisRequest(final HttpServletRequest request,
|
|
|
+ final HttpServletResponse response, final FilterChain chain) {
|
|
|
+
|
|
|
+ int status = 0;
|
|
|
+ String errMsg = StringUtil.EMPTY;
|
|
|
+ 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(escapeXml(fEntry.getKey())).append("\">");
|
|
|
+ for (final Map.Entry<String, List<Map<String, Object>>> aEntry : fEntry
|
|
|
+ .getValue().entrySet()) {
|
|
|
+ buf.append("<analysis name=\"")
|
|
|
+ .append(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(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\" standalone=\"no\"?>");
|
|
|
+ buf.append("<GSP VER=\"");
|
|
|
+ buf.append(Constants.GSA_API_VERSION);
|
|
|
+ buf.append("\">");
|
|
|
+// buf.append("<status>");
|
|
|
+// buf.append(status);
|
|
|
+// buf.append("</status>");
|
|
|
+ if (status == 0) {
|
|
|
+ buf.append(body);
|
|
|
+ } else {
|
|
|
+ buf.append("<message>");
|
|
|
+ buf.append(escapeXml(errMsg));
|
|
|
+ buf.append("</message>");
|
|
|
+ }
|
|
|
+ buf.append("</GSP>");
|
|
|
+ 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 instanceof Date) {
|
|
|
+ final SimpleDateFormat sdf = new SimpleDateFormat(
|
|
|
+ CoreLibConstants.DATE_FORMAT_ISO_8601_EXTEND);
|
|
|
+ buf.append(StringEscapeUtils.escapeXml(sdf.format(obj)));
|
|
|
+ } else if (obj != null) {
|
|
|
+ buf.append(StringEscapeUtils.escapeXml(obj.toString()));
|
|
|
+ }
|
|
|
+ return buf.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getXmlPathPrefix() {
|
|
|
+ return gsaPathPrefix;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setXmlPathPrefix(final String xmlPathPrefix) {
|
|
|
+ this.gsaPathPrefix = xmlPathPrefix;
|
|
|
+ }
|
|
|
+}
|