GSA API support

This commit is contained in:
Kaoru FUZITA 2015-07-16 19:15:02 +09:00
parent 26179d2011
commit 66e5be9241
4 changed files with 739 additions and 2 deletions

View file

@ -36,6 +36,8 @@ public class Constants extends CoreLibConstants {
public static final String WEB_API_VERSION = FESS_VERSION;
public static final String GSA_API_VERSION = "3.2";
public static final String TRUE = "true";
public static final String FALSE = "false";

View file

@ -129,6 +129,15 @@ public class IndexAction {
protected static final Pattern FIELD_EXTRACTION_PATTERN = Pattern
.compile("^([a-zA-Z0-9_]+):.*");
// GSA
private static final String GSA_QUERY = "q";
private static final String GSA_SITE = "site";
private static final String GSA_REQUIRED_FIELDS = "requiredfields";
private static final String GSA_GET_FIELDS = "getfields";
@ActionForm
@Resource
protected IndexForm indexForm;
@ -593,6 +602,60 @@ public class IndexAction {
return null;
}
@Execute(validator = false)
public String gsaSearchApi() {
try {
// query words
indexForm.query = (String) request.getParameter(GSA_QUERY);
WebApiUtil.setObject("searchQueryOriginal", indexForm.query);
// collections
List<String> additional = new ArrayList<String>();
final String site = (String) request.getParameter(GSA_SITE);
if (StringUtil.isNotBlank(site)) {
additional.add(" (label:"
+ site.replace(".", " AND label:").replace("|",
" OR label:") + ")");
}
// dynmic fields
final String requiredFields = (String) request
.getParameter(GSA_REQUIRED_FIELDS);
if (StringUtil.isNotBlank(requiredFields)) {
additional.add(" (MT_"
+ requiredFields.replace(":", "_s:")
.replace(".", " AND MT_")
.replace("|", " OR MT_") + ")");
}
if (additional.size() > 0) {
indexForm.additional = (String[]) additional
.toArray(new String[additional.size()]);
}
// meta tags should be returned
final String getFields = (String) request
.getParameter(GSA_GET_FIELDS);
if (StringUtil.isNotBlank(getFields)) {
WebApiUtil.setObject("getFields",
Arrays.asList(getFields.split("\\.")));
} else {
WebApiUtil.setObject("getFields", new ArrayList<String>());
}
WebApiUtil.setObject("searchQuery", doSearchInternal());
WebApiUtil.setObject("searchTime", searchTime);
WebApiUtil.setObject("queryTime", queryTime);
WebApiUtil.setObject("execTime", execTime);
WebApiUtil.setObject("pageSize", pageSize);
WebApiUtil.setObject("currentPageNumber", currentPageNumber);
WebApiUtil.setObject("allRecordCount", allRecordCount);
WebApiUtil.setObject("allPageCount", allPageCount);
WebApiUtil.setObject("documentItems", documentItems);
WebApiUtil.setObject("facetResponse", facetResponse);
WebApiUtil.setObject("moreLikeThisResponse", moreLikeThisResponse);
} catch (final Exception e) {
WebApiUtil.setError(1, e);
}
return null;
}
@Execute(validator = false)
public String suggestApi() {
if (Constants.FALSE.equals(crawlerProperties.getProperty(
@ -621,7 +684,7 @@ public class IndexAction {
}
final String[] fieldNames = indexForm.fn;
final String[] labels = indexForm.fields.get("label");
final String[] labels = indexForm.fields.get(LABEL_FIELD);
final List<SuggestResponse> suggestResultList = new ArrayList<SuggestResponse>();
WebApiUtil.setObject("suggestResultList", suggestResultList);
@ -687,7 +750,7 @@ public class IndexAction {
}
final String[] fieldNames = indexForm.fn;
final String[] labels = indexForm.fields.get("label");
final String[] labels = indexForm.fields.get(LABEL_FIELD);
final List<SpellCheckResponse> spellCheckResultList = new ArrayList<SpellCheckResponse>();
WebApiUtil.setObject("spellCheckResultList", spellCheckResultList);

View file

@ -31,6 +31,8 @@ public class BaseApiManager {
protected static final String SEARCH_API = "/searchApi";
protected static final String GSA_SEARCH_API = "/gsaSearchApi";
protected static enum FormatType {
SEARCH, LABEL, SUGGEST, SPELLCHECK, ANALYSIS, HOTSEARCHWORD, FAVORITE, FAVORITES, OTHER, PING;
}

View file

@ -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;
}
}