mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V2.0 to HEAD
svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V2.0@5118 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V2.0@5119 . - OpenSearch Proxy svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V2.0@5121 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V2.0@5122 . - Extract sample OpenSearch engine registrations into extension config file. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5125 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
43
config/alfresco/extension/web-api-config-custom.xml.sample
Normal file
43
config/alfresco/extension/web-api-config-custom.xml.sample
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<!-- -->
|
||||||
|
<!-- Example configuration of multiple OpenSearch engines -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<alfresco-config>
|
||||||
|
|
||||||
|
<config evaluator="string-compare" condition="OpenSearch">
|
||||||
|
<opensearch>
|
||||||
|
|
||||||
|
<engines>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Example: Registration of remote Alfresco Server -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<!-- TODO: Find/Replace [host] with server host name -->
|
||||||
|
<!-- TODO: Find/Replace [port] with server port number -->
|
||||||
|
|
||||||
|
<engine label="Remote Alfresco Repository" proxy="remote">
|
||||||
|
<url type="application/atom+xml">
|
||||||
|
http://[host]:[port]/alfresco/service/search/keyword?q={searchTerms}&p={startPage?}&c={count?}&l={language?}&guest=true&format=atom
|
||||||
|
</url>
|
||||||
|
<url type="application/rss+xml">
|
||||||
|
http://[host]:[port]/alfresco/service/search/keyword?q={searchTerms}&p={startPage?}&c={count?}&l={language?}&guest=true&format=rss
|
||||||
|
</url>
|
||||||
|
</engine>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Example: Registration of Alfresco's Open Talk Blog -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<engine label="Alfresco Open Source Talk" proxy="opentalk">
|
||||||
|
<url type="application/rss+xml">
|
||||||
|
http://blogs.alfresco.com/opentalk/os-query?s={searchTerms}&itemstart={startIndex?}&itempage={startPage?}&itemlimit={count?}
|
||||||
|
</url>
|
||||||
|
</engine>
|
||||||
|
|
||||||
|
</engines>
|
||||||
|
|
||||||
|
</opensearch>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
</alfresco-config>
|
@@ -11,6 +11,7 @@
|
|||||||
<constructor-arg>
|
<constructor-arg>
|
||||||
<list>
|
<list>
|
||||||
<value>classpath:alfresco/web-api-config.xml</value>
|
<value>classpath:alfresco/web-api-config.xml</value>
|
||||||
|
<value>classpath:alfresco/extension/web-api-config-custom.xml</value>
|
||||||
</list>
|
</list>
|
||||||
</constructor-arg>
|
</constructor-arg>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -136,8 +137,16 @@
|
|||||||
<bean id="web.api.SearchEngines" class="org.alfresco.web.api.services.SearchEngines" parent="web.api.APITemplateService">
|
<bean id="web.api.SearchEngines" class="org.alfresco.web.api.services.SearchEngines" parent="web.api.APITemplateService">
|
||||||
<property name="httpUri" value="/search/engines" />
|
<property name="httpUri" value="/search/engines" />
|
||||||
<property name="configService" ref="web.api.Config" />
|
<property name="configService" ref="web.api.Config" />
|
||||||
|
<property name="searchProxy" ref="web.api.SearchProxy" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<!-- Alfresco (OpenSearch) Proxy -->
|
||||||
|
<bean id="web.api.SearchProxy" class="org.alfresco.web.api.services.SearchProxy" parent="web.api.APIService">
|
||||||
|
<property name="httpUri" value="/search/engine" />
|
||||||
|
<property name="configService" ref="web.api.Config" />
|
||||||
|
<property name="formatRegistry" ref="web.api.FormatRegistry" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- Alfresco Web Client Keyword Search Description (OpenSearch) -->
|
<!-- Alfresco Web Client Keyword Search Description (OpenSearch) -->
|
||||||
<bean id="web.api.KeywordSearchDescription" class="org.alfresco.web.api.services.KeywordSearchDescription" parent="web.api.APITemplateService">
|
<bean id="web.api.KeywordSearchDescription" class="org.alfresco.web.api.services.KeywordSearchDescription" parent="web.api.APITemplateService">
|
||||||
<property name="httpUri" value="/search/keywordsearchdescription.xml" />
|
<property name="httpUri" value="/search/keywordsearchdescription.xml" />
|
||||||
@@ -148,5 +157,5 @@
|
|||||||
<property name="httpUri" value="/search/keyword" />
|
<property name="httpUri" value="/search/keyword" />
|
||||||
<property name="searchService" ref="SearchService" />
|
<property name="searchService" ref="SearchService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -10,18 +10,20 @@
|
|||||||
</element-readers>
|
</element-readers>
|
||||||
</plug-ins>
|
</plug-ins>
|
||||||
|
|
||||||
<config>
|
|
||||||
<!-- TODO: host, port?? -->
|
|
||||||
</config>
|
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
<!-- -->
|
|
||||||
<!-- Configuration of Open Search API -->
|
<!-- Configuration of Open Search API -->
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
|
||||||
<config evaluator="string-compare" condition="OpenSearch">
|
<config evaluator="string-compare" condition="OpenSearch">
|
||||||
<opensearch>
|
<opensearch>
|
||||||
|
|
||||||
<engines>
|
<engines>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Local Alfresco Repository -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
<engine label-id="current_repo" label="Alfresco Keyword Search">
|
<engine label-id="current_repo" label="Alfresco Keyword Search">
|
||||||
<url type="application/opensearchdescription+xml">
|
<url type="application/opensearchdescription+xml">
|
||||||
/service/search/keywordsearchdescription.xml
|
/service/search/keywordsearchdescription.xml
|
||||||
@@ -36,7 +38,14 @@
|
|||||||
/service/search/keyword?q={searchTerms}&p={startPage?}&c={count?}&l={language?}&guest={alf:guest?}
|
/service/search/keyword?q={searchTerms}&p={startPage?}&c={count?}&l={language?}&guest={alf:guest?}
|
||||||
</url>
|
</url>
|
||||||
</engine>
|
</engine>
|
||||||
|
|
||||||
</engines>
|
</engines>
|
||||||
|
|
||||||
|
<proxy>
|
||||||
|
<!-- URL of Search Engine proxy -->
|
||||||
|
<url>/service/search/engine</url>
|
||||||
|
</proxy>
|
||||||
|
|
||||||
</opensearch>
|
</opensearch>
|
||||||
</config>
|
</config>
|
||||||
|
|
||||||
|
@@ -91,6 +91,29 @@ public class APIRequest extends HttpServletRequestWrapper
|
|||||||
return getPath() + getServletPath();
|
return getPath() + getServletPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the path extension beyond the path registered for this service
|
||||||
|
*
|
||||||
|
* e.g.
|
||||||
|
* a) service registered path = /search/engine
|
||||||
|
* b) request path = /search/engine/external
|
||||||
|
*
|
||||||
|
* => /external
|
||||||
|
*
|
||||||
|
* @return extension path
|
||||||
|
*/
|
||||||
|
public String getExtensionPath(APIService service)
|
||||||
|
{
|
||||||
|
String servicePath = service.getHttpUri();
|
||||||
|
String extensionPath = getPathInfo();
|
||||||
|
int extIdx = extensionPath.indexOf(servicePath);
|
||||||
|
if (extIdx != -1)
|
||||||
|
{
|
||||||
|
extensionPath = extensionPath.substring(extIdx + servicePath.length() + 1 /* exclude leading / */);
|
||||||
|
}
|
||||||
|
return extensionPath;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the full request URL
|
* Gets the full request URL
|
||||||
*
|
*
|
||||||
|
@@ -116,7 +116,7 @@ public class APIServiceRegistry
|
|||||||
// TODO: Replace with more efficient approach
|
// TODO: Replace with more efficient approach
|
||||||
for (int i = 0; i < services.size(); i++)
|
for (int i = 0; i < services.size(); i++)
|
||||||
{
|
{
|
||||||
if (methods.get(i).equals(method) && uris.get(i).equals(uri))
|
if (methods.get(i).equals(method) && uri.startsWith(uris.get(i)))
|
||||||
{
|
{
|
||||||
apiService = services.get(i);
|
apiService = services.get(i);
|
||||||
break;
|
break;
|
||||||
|
@@ -34,7 +34,9 @@ public class FormatRegistry
|
|||||||
private static final Log logger = LogFactory.getLog(FormatRegistry.class);
|
private static final Log logger = LogFactory.getLog(FormatRegistry.class);
|
||||||
|
|
||||||
private Map<String, String> formats;
|
private Map<String, String> formats;
|
||||||
|
private Map<String, String> mimetypes;
|
||||||
private Map<String, Map<String, String>> agentFormats;
|
private Map<String, Map<String, String>> agentFormats;
|
||||||
|
private Map<String, Map<String, String>> agentMimetypes;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,7 +45,9 @@ public class FormatRegistry
|
|||||||
public FormatRegistry()
|
public FormatRegistry()
|
||||||
{
|
{
|
||||||
formats = new HashMap<String, String>();
|
formats = new HashMap<String, String>();
|
||||||
|
mimetypes = new HashMap<String, String>();
|
||||||
agentFormats = new HashMap<String, Map<String, String>>();
|
agentFormats = new HashMap<String, Map<String, String>>();
|
||||||
|
agentMimetypes = new HashMap<String, Map<String, String>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,13 +60,16 @@ public class FormatRegistry
|
|||||||
{
|
{
|
||||||
// retrieve formats list for agent
|
// retrieve formats list for agent
|
||||||
Map<String, String> formatsForAgent = formats;
|
Map<String, String> formatsForAgent = formats;
|
||||||
|
Map<String, String> mimetypesForAgent = mimetypes;
|
||||||
if (agent != null)
|
if (agent != null)
|
||||||
{
|
{
|
||||||
formatsForAgent = agentFormats.get(agent);
|
formatsForAgent = agentFormats.get(agent);
|
||||||
if (formatsForAgent == null)
|
if (formatsForAgent == null)
|
||||||
{
|
{
|
||||||
formatsForAgent = new HashMap<String, String>();
|
formatsForAgent = new HashMap<String, String>();
|
||||||
|
mimetypesForAgent = new HashMap<String, String>();
|
||||||
agentFormats.put(agent, formatsForAgent);
|
agentFormats.put(agent, formatsForAgent);
|
||||||
|
agentMimetypes.put(agent, mimetypesForAgent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +85,7 @@ public class FormatRegistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
formatsForAgent.put(entry.getKey(), entry.getValue());
|
formatsForAgent.put(entry.getKey(), entry.getValue());
|
||||||
|
mimetypesForAgent.put(entry.getValue(), entry.getKey());
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Registered API format '" + entry.getKey() + "' with mime type '" + entry.getValue() + "' (agent: " + agent + ")");
|
logger.debug("Registered API format '" + entry.getKey() + "' with mime type '" + entry.getValue() + "' (agent: " + agent + ")");
|
||||||
@@ -111,5 +119,33 @@ public class FormatRegistry
|
|||||||
|
|
||||||
return mimetype;
|
return mimetype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the format for the specified user agent and mimetype
|
||||||
|
*
|
||||||
|
* @param agent
|
||||||
|
* @param mimetype
|
||||||
|
* @return format (or null, if one is not registered)
|
||||||
|
*/
|
||||||
|
public String getFormat(String agent, String mimetype)
|
||||||
|
{
|
||||||
|
String format = null;
|
||||||
|
|
||||||
|
if (agent != null)
|
||||||
|
{
|
||||||
|
Map<String, String> mimetypesForAgent = agentMimetypes.get(agent);
|
||||||
|
if (mimetypesForAgent != null)
|
||||||
|
{
|
||||||
|
format = mimetypesForAgent.get(mimetype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == null)
|
||||||
|
{
|
||||||
|
format = mimetypes.get(mimetype);
|
||||||
|
}
|
||||||
|
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,7 @@ public class SearchEngines extends APIServiceTemplateImpl
|
|||||||
|
|
||||||
// dependencies
|
// dependencies
|
||||||
protected ConfigService configService;
|
protected ConfigService configService;
|
||||||
|
protected SearchProxy searchProxy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param configService
|
* @param configService
|
||||||
@@ -60,6 +61,14 @@ public class SearchEngines extends APIServiceTemplateImpl
|
|||||||
this.configService = configService;
|
this.configService = configService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param searchProxy
|
||||||
|
*/
|
||||||
|
public void setSearchProxy(SearchProxy searchProxy)
|
||||||
|
{
|
||||||
|
this.searchProxy = searchProxy;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.web.api.APIService#getRequiredAuthentication()
|
* @see org.alfresco.web.api.APIService#getRequiredAuthentication()
|
||||||
*/
|
*/
|
||||||
@@ -135,7 +144,7 @@ public class SearchEngines extends APIServiceTemplateImpl
|
|||||||
for (Map.Entry<String, String> engineUrl : engineUrls.entrySet())
|
for (Map.Entry<String, String> engineUrl : engineUrls.entrySet())
|
||||||
{
|
{
|
||||||
String type = engineUrl.getKey();
|
String type = engineUrl.getKey();
|
||||||
String url = engineUrl.getValue();
|
String url = searchProxy.createUrl(engineConfig, type);
|
||||||
|
|
||||||
if ((urlType.equals(URL_ARG_ALL)) ||
|
if ((urlType.equals(URL_ARG_ALL)) ||
|
||||||
(urlType.equals(URL_ARG_DESCRIPTION) && type.equals(MimetypeMap.MIMETYPE_OPENSEARCH_DESCRIPTION)) ||
|
(urlType.equals(URL_ARG_DESCRIPTION) && type.equals(MimetypeMap.MIMETYPE_OPENSEARCH_DESCRIPTION)) ||
|
||||||
|
337
source/java/org/alfresco/web/api/services/SearchProxy.java
Normal file
337
source/java/org/alfresco/web/api/services/SearchProxy.java
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
package org.alfresco.web.api.services;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.alfresco.config.Config;
|
||||||
|
import org.alfresco.config.ConfigService;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.web.api.APIException;
|
||||||
|
import org.alfresco.web.api.APIRequest;
|
||||||
|
import org.alfresco.web.api.APIResponse;
|
||||||
|
import org.alfresco.web.api.FormatRegistry;
|
||||||
|
import org.alfresco.web.api.APIRequest.HttpMethod;
|
||||||
|
import org.alfresco.web.api.APIRequest.RequiredAuthentication;
|
||||||
|
import org.alfresco.web.app.servlet.HTTPProxy;
|
||||||
|
import org.alfresco.web.config.OpenSearchConfigElement;
|
||||||
|
import org.alfresco.web.config.OpenSearchConfigElement.EngineConfig;
|
||||||
|
import org.alfresco.web.config.OpenSearchConfigElement.ProxyConfig;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.dom4j.Attribute;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.dom4j.XPath;
|
||||||
|
import org.dom4j.io.OutputFormat;
|
||||||
|
import org.dom4j.io.SAXReader;
|
||||||
|
import org.dom4j.io.XMLWriter;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alfresco OpenSearch Proxy Service
|
||||||
|
*
|
||||||
|
* Provides the ability to submit a request to a registered search engine
|
||||||
|
* via the Alfresco server.
|
||||||
|
*
|
||||||
|
* @author davidc
|
||||||
|
*/
|
||||||
|
public class SearchProxy extends APIServiceImpl implements InitializingBean
|
||||||
|
{
|
||||||
|
// Logger
|
||||||
|
private static final Log logger = LogFactory.getLog(SearchProxy.class);
|
||||||
|
|
||||||
|
// dependencies
|
||||||
|
protected FormatRegistry formatRegistry;
|
||||||
|
protected ConfigService configService;
|
||||||
|
protected OpenSearchConfigElement searchConfig;
|
||||||
|
protected String proxyPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param formatRegistry
|
||||||
|
*/
|
||||||
|
public void setFormatRegistry(FormatRegistry formatRegistry)
|
||||||
|
{
|
||||||
|
this.formatRegistry = formatRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param configService
|
||||||
|
*/
|
||||||
|
public void setConfigService(ConfigService configService)
|
||||||
|
{
|
||||||
|
this.configService = configService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.api.APIService#getRequiredAuthentication()
|
||||||
|
*/
|
||||||
|
public RequiredAuthentication getRequiredAuthentication()
|
||||||
|
{
|
||||||
|
return APIRequest.RequiredAuthentication.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.api.APIService#getHttpMethod()
|
||||||
|
*/
|
||||||
|
public HttpMethod getHttpMethod()
|
||||||
|
{
|
||||||
|
return APIRequest.HttpMethod.GET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.api.APIService#getDefaultFormat()
|
||||||
|
*/
|
||||||
|
public String getDefaultFormat()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.api.APIService#getDescription()
|
||||||
|
*/
|
||||||
|
public String getDescription()
|
||||||
|
{
|
||||||
|
return "Issue an OpenSearch query via Alfresco";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||||
|
*/
|
||||||
|
public void afterPropertiesSet() throws Exception
|
||||||
|
{
|
||||||
|
Config config = configService.getConfig("OpenSearch");
|
||||||
|
searchConfig = (OpenSearchConfigElement)config.getConfigElement(OpenSearchConfigElement.CONFIG_ELEMENT_ID);
|
||||||
|
if (searchConfig == null)
|
||||||
|
{
|
||||||
|
throw new APIException("OpenSearch configuration not found");
|
||||||
|
}
|
||||||
|
ProxyConfig proxyConfig = searchConfig.getProxy();
|
||||||
|
if (proxyConfig == null)
|
||||||
|
{
|
||||||
|
throw new APIException("OpenSearch proxy configuration not found");
|
||||||
|
}
|
||||||
|
proxyPath = proxyConfig.getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.api.APIService#execute(org.alfresco.web.api.APIRequest, org.alfresco.web.api.APIResponse)
|
||||||
|
*/
|
||||||
|
public void execute(APIRequest req, APIResponse res)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
String extensionPath = req.getExtensionPath(this);
|
||||||
|
String[] extensionPaths = extensionPath.split("/");
|
||||||
|
if (extensionPaths.length != 2)
|
||||||
|
{
|
||||||
|
throw new APIException("OpenSearch engine has not been specified as /<engine>/<format>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve search engine configuration
|
||||||
|
String engine = extensionPaths[0];
|
||||||
|
EngineConfig engineConfig = searchConfig.getEngine(engine);
|
||||||
|
if (engineConfig == null)
|
||||||
|
{
|
||||||
|
throw new APIException("OpenSearch engine '" + engine + "' does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve engine url as specified by format
|
||||||
|
String format = extensionPaths[1];
|
||||||
|
String mimetype = formatRegistry.getMimeType(null, format);
|
||||||
|
if (mimetype == null)
|
||||||
|
{
|
||||||
|
throw new APIException("Format '" + format + "' does not map to a registered mimetype");
|
||||||
|
}
|
||||||
|
Map<String, String> engineUrls = engineConfig.getUrls();
|
||||||
|
String engineUrl = engineUrls.get(mimetype);
|
||||||
|
if (engineUrl == null)
|
||||||
|
{
|
||||||
|
throw new APIException("Url mimetype '" + mimetype + "' does not exist for engine '" + engine + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace template url arguments with actual arguments specified on request
|
||||||
|
int engineUrlArgIdx = engineUrl.indexOf("?");
|
||||||
|
if (engineUrlArgIdx != -1)
|
||||||
|
{
|
||||||
|
engineUrl = engineUrl.substring(0, engineUrlArgIdx);
|
||||||
|
}
|
||||||
|
if (req.getQueryString() != null)
|
||||||
|
{
|
||||||
|
engineUrl += "?" + req.getQueryString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Mapping engine '" + engine + "' (mimetype '" + mimetype + "') to url '" + engineUrl + "'");
|
||||||
|
|
||||||
|
// issue request against search engine
|
||||||
|
SearchEngineHttpProxy proxy = new SearchEngineHttpProxy(req.getPath(), engine, engineUrl, res);
|
||||||
|
proxy.service();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenSearch HTTPProxy
|
||||||
|
*
|
||||||
|
* This proxy remaps OpenSearch links (e.g. previous, next) found in search results.
|
||||||
|
*
|
||||||
|
* @author davidc
|
||||||
|
*/
|
||||||
|
private class SearchEngineHttpProxy extends HTTPProxy
|
||||||
|
{
|
||||||
|
private final static String ATOM_NS_URI = "http://www.w3.org/2005/Atom";
|
||||||
|
private final static String ATOM_NS_PREFIX = "atom";
|
||||||
|
private final static String ATOM_LINK_XPATH = "atom:link[@rel=\"first\" or @rel=\"last\" or @rel=\"next\" or @rel=\"previous\" or @rel=\"self\" or @rel=\"alternate\"]";
|
||||||
|
private String engine;
|
||||||
|
private String rootPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct
|
||||||
|
*
|
||||||
|
* @param requestUrl
|
||||||
|
* @param response
|
||||||
|
* @throws MalformedURLException
|
||||||
|
*/
|
||||||
|
public SearchEngineHttpProxy(String rootPath, String engine, String engineUrl, HttpServletResponse response)
|
||||||
|
throws MalformedURLException
|
||||||
|
{
|
||||||
|
super(engineUrl.startsWith("/") ? rootPath + engineUrl : engineUrl, response);
|
||||||
|
this.engine = engine;
|
||||||
|
this.rootPath = rootPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.app.servlet.HTTPProxy#writeResponse(java.io.InputStream, java.io.OutputStream)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void writeResponse(InputStream input, OutputStream output)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (response.getContentType().startsWith(MimetypeMap.MIMETYPE_ATOM) ||
|
||||||
|
response.getContentType().startsWith(MimetypeMap.MIMETYPE_RSS))
|
||||||
|
{
|
||||||
|
// Only post-process ATOM and RSS feeds
|
||||||
|
// Replace all navigation links with "proxied" versions
|
||||||
|
SAXReader reader = new SAXReader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Document document = reader.read(input);
|
||||||
|
Element rootElement = document.getRootElement();
|
||||||
|
|
||||||
|
XPath xpath = rootElement.createXPath(ATOM_LINK_XPATH);
|
||||||
|
Map<String,String> uris = new HashMap<String,String>();
|
||||||
|
uris.put(ATOM_NS_PREFIX, ATOM_NS_URI);
|
||||||
|
xpath.setNamespaceURIs(uris);
|
||||||
|
|
||||||
|
List nodes = xpath.selectNodes(rootElement);
|
||||||
|
Iterator iter = nodes.iterator();
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
Element element = (Element)iter.next();
|
||||||
|
Attribute hrefAttr = element.attribute("href");
|
||||||
|
String mimetype = element.attributeValue("type");
|
||||||
|
if (mimetype == null || mimetype.length() == 0)
|
||||||
|
{
|
||||||
|
mimetype = MimetypeMap.MIMETYPE_HTML;
|
||||||
|
}
|
||||||
|
String url = createUrl(engine, hrefAttr.getValue(), mimetype);
|
||||||
|
if (url.startsWith("/"))
|
||||||
|
{
|
||||||
|
url = rootPath + url;
|
||||||
|
}
|
||||||
|
hrefAttr.setValue(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputFormat outputFormat = OutputFormat.createPrettyPrint();
|
||||||
|
XMLWriter writer = new XMLWriter(output, outputFormat);
|
||||||
|
writer.write(rootElement);
|
||||||
|
writer.flush();
|
||||||
|
}
|
||||||
|
catch(DocumentException e)
|
||||||
|
{
|
||||||
|
throw new IOException(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
super.writeResponse(input, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a "proxied" search engine url
|
||||||
|
*
|
||||||
|
* @param engine engine name (as identified by <engine proxy="<name>">)
|
||||||
|
* @param mimetype url to proxy (as identified by mimetype)
|
||||||
|
* @return "proxied" url
|
||||||
|
*/
|
||||||
|
public String createUrl(OpenSearchConfigElement.EngineConfig engine, String mimetype)
|
||||||
|
{
|
||||||
|
Map<String, String> urls = engine.getUrls();
|
||||||
|
String url = urls.get(mimetype);
|
||||||
|
if (url != null)
|
||||||
|
{
|
||||||
|
String proxy = engine.getProxy();
|
||||||
|
if (proxy != null && !mimetype.equals(MimetypeMap.MIMETYPE_OPENSEARCH_DESCRIPTION))
|
||||||
|
{
|
||||||
|
url = createUrl(proxy, url, mimetype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a "proxied" search engine url
|
||||||
|
*
|
||||||
|
* @param engine engine name (as identified by <engine proxy="<name>">)
|
||||||
|
* @param url engine url
|
||||||
|
* @param mimetype mimetype of url
|
||||||
|
* @return "proxied" url
|
||||||
|
*/
|
||||||
|
public String createUrl(String engine, String url, String mimetype)
|
||||||
|
{
|
||||||
|
String format = formatRegistry.getFormat(null, mimetype);
|
||||||
|
if (format == null)
|
||||||
|
{
|
||||||
|
throw new APIException("Mimetype '" + mimetype + "' is not registered.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxyUrl = null;
|
||||||
|
int argIdx = url.indexOf("?");
|
||||||
|
if (argIdx == -1)
|
||||||
|
{
|
||||||
|
proxyUrl = proxyPath + "/" + engine + "/" + format;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proxyUrl = proxyPath + "/" + engine + "/" + format + url.substring(argIdx);
|
||||||
|
}
|
||||||
|
return proxyUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
134
source/java/org/alfresco/web/app/servlet/HTTPProxy.java
Normal file
134
source/java/org/alfresco/web/app/servlet/HTTPProxy.java
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
package org.alfresco.web.app.servlet;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple server-side HTTP Request / Response
|
||||||
|
*
|
||||||
|
* @author davidc
|
||||||
|
*/
|
||||||
|
public class HTTPProxy
|
||||||
|
{
|
||||||
|
protected URL url;
|
||||||
|
protected HttpServletResponse response;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct
|
||||||
|
*
|
||||||
|
* @param requestUrl url to request
|
||||||
|
* @param response response to write request back to
|
||||||
|
* @throws MalformedURLException
|
||||||
|
*/
|
||||||
|
public HTTPProxy(String requestUrl, HttpServletResponse response)
|
||||||
|
throws MalformedURLException
|
||||||
|
{
|
||||||
|
this.url = new URL(requestUrl);
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform request
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void service()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
URLConnection connection = url.openConnection();
|
||||||
|
initialiseResponse(connection);
|
||||||
|
InputStream input = connection.getInputStream();
|
||||||
|
OutputStream output = response.getOutputStream();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writeResponse(input, output);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (input != null)
|
||||||
|
{
|
||||||
|
input.close();
|
||||||
|
}
|
||||||
|
if (output != null)
|
||||||
|
{
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise response
|
||||||
|
*
|
||||||
|
* @param urlConnection url connection
|
||||||
|
*/
|
||||||
|
protected void initialiseResponse(URLConnection urlConnection)
|
||||||
|
{
|
||||||
|
String type = urlConnection.getContentType();
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
int encodingIdx = type.lastIndexOf("charset=");
|
||||||
|
if (encodingIdx == -1)
|
||||||
|
{
|
||||||
|
String encoding = urlConnection.getContentEncoding();
|
||||||
|
if (encoding != null && encoding.length() > 0)
|
||||||
|
{
|
||||||
|
type += ";charset=" + encoding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setContentType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write response
|
||||||
|
*
|
||||||
|
* @param input input stream of request
|
||||||
|
* @param output output stream of response
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void writeResponse(InputStream input, OutputStream output)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int read = input.read(buffer);
|
||||||
|
while (read != -1)
|
||||||
|
{
|
||||||
|
output.write(buffer, 0, read);
|
||||||
|
read = input.read(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
119
source/java/org/alfresco/web/app/servlet/HTTPProxyServlet.java
Normal file
119
source/java/org/alfresco/web/app/servlet/HTTPProxyServlet.java
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
package org.alfresco.web.app.servlet;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP Proxy Servlet
|
||||||
|
*
|
||||||
|
* Provides the ability to submit a URL request via the Alfresco Server i.e.
|
||||||
|
* the Alfresco server acts as a proxy.
|
||||||
|
*
|
||||||
|
* This servlet accepts:
|
||||||
|
*
|
||||||
|
* /proxy?endpoint=<endpointUrl>[&<argName>=<argValue>]*
|
||||||
|
*
|
||||||
|
* Where:
|
||||||
|
*
|
||||||
|
* - endpointUrl is the URL to make a request against
|
||||||
|
* - argName is the name of a URL argument to append to the request
|
||||||
|
* - argValue is the value of URL argument
|
||||||
|
*
|
||||||
|
* E.g.:
|
||||||
|
*
|
||||||
|
* /proxy?endpoint=http://www.alfresco.com&arg1=value1&arg2=value2
|
||||||
|
*
|
||||||
|
* @author davidc
|
||||||
|
*/
|
||||||
|
public class HTTPProxyServlet extends BaseServlet
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -576405943603122206L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||||
|
*/
|
||||||
|
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
||||||
|
throws ServletException, IOException
|
||||||
|
{
|
||||||
|
String endpoint = null;
|
||||||
|
String args = null;
|
||||||
|
|
||||||
|
Map<String, String[]> parameters = req.getParameterMap();
|
||||||
|
for (Map.Entry<String, String[]> parameter : parameters.entrySet())
|
||||||
|
{
|
||||||
|
String[] values = parameter.getValue();
|
||||||
|
int startIdx = 0;
|
||||||
|
|
||||||
|
if (parameter.getKey().equals("endpoint") && values.length > 0)
|
||||||
|
{
|
||||||
|
endpoint = values[0];
|
||||||
|
startIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = startIdx; i < values.length; i++)
|
||||||
|
{
|
||||||
|
String arg = parameter.getKey() + "=" + values[i];
|
||||||
|
args = (args == null) ? arg : args + "&" + arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endpoint == null || endpoint.length() == 0)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("endpoint argument not specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = endpoint + ((args == null) ? "" : "?" + args);
|
||||||
|
HTTPProxy proxy = new HTTPProxy(url, res);
|
||||||
|
proxy.service();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a "proxied" URL
|
||||||
|
*
|
||||||
|
* Note: the "proxied" URL is a relative url
|
||||||
|
*
|
||||||
|
* @param url the URL to proxy
|
||||||
|
* @return the "proxied" url
|
||||||
|
*/
|
||||||
|
public static String createProxyUrl(String url)
|
||||||
|
{
|
||||||
|
String proxy = "/proxy";
|
||||||
|
if (url != null && url.length() > 0)
|
||||||
|
{
|
||||||
|
int argIndex = url.lastIndexOf("?");
|
||||||
|
if (argIndex == -1)
|
||||||
|
{
|
||||||
|
proxy += "?endpoint=" + url;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proxy += "?endpoint=" + url.substring(0, argIndex) + "&" + url.substring(argIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -37,8 +37,10 @@ public class OpenSearchConfigElement extends ConfigElementAdapter
|
|||||||
{
|
{
|
||||||
public static final String CONFIG_ELEMENT_ID = "opensearch";
|
public static final String CONFIG_ELEMENT_ID = "opensearch";
|
||||||
|
|
||||||
|
private ProxyConfig proxy;
|
||||||
private Set<EngineConfig> engines = new HashSet<EngineConfig>(8, 10f);
|
private Set<EngineConfig> engines = new HashSet<EngineConfig>(8, 10f);
|
||||||
|
private Map<String, EngineConfig> enginesByProxy = new HashMap<String, EngineConfig>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
@@ -85,10 +87,37 @@ public class OpenSearchConfigElement extends ConfigElementAdapter
|
|||||||
{
|
{
|
||||||
combinedElement.addEngine(plugin);
|
combinedElement.addEngine(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the proxy configuration
|
||||||
|
ProxyConfig proxyConfig = this.getProxy();
|
||||||
|
if (proxyConfig != null)
|
||||||
|
{
|
||||||
|
combinedElement.setProxy(proxyConfig);
|
||||||
|
}
|
||||||
|
|
||||||
return combinedElement;
|
return combinedElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the proxy configuration
|
||||||
|
*
|
||||||
|
* @param proxyConfig
|
||||||
|
*/
|
||||||
|
/*package*/ void setProxy(ProxyConfig proxyConfig)
|
||||||
|
{
|
||||||
|
this.proxy = proxyConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the proxy configuration
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ProxyConfig getProxy()
|
||||||
|
{
|
||||||
|
return this.proxy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns a set of the engines
|
* @return Returns a set of the engines
|
||||||
*/
|
*/
|
||||||
@@ -96,6 +125,15 @@ public class OpenSearchConfigElement extends ConfigElementAdapter
|
|||||||
{
|
{
|
||||||
return this.engines;
|
return this.engines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param proxy name of engine proxy
|
||||||
|
* @return associated engine config (or null, if none registered against proxy)
|
||||||
|
*/
|
||||||
|
public EngineConfig getEngine(String proxy)
|
||||||
|
{
|
||||||
|
return this.enginesByProxy.get(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an engine
|
* Adds an engine
|
||||||
@@ -105,6 +143,11 @@ public class OpenSearchConfigElement extends ConfigElementAdapter
|
|||||||
/*package*/ void addEngine(EngineConfig engineConfig)
|
/*package*/ void addEngine(EngineConfig engineConfig)
|
||||||
{
|
{
|
||||||
this.engines.add(engineConfig);
|
this.engines.add(engineConfig);
|
||||||
|
String proxy = engineConfig.getProxy();
|
||||||
|
if (proxy != null && proxy.length() > 0)
|
||||||
|
{
|
||||||
|
this.enginesByProxy.put(proxy, engineConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -117,8 +160,10 @@ public class OpenSearchConfigElement extends ConfigElementAdapter
|
|||||||
{
|
{
|
||||||
protected String label;
|
protected String label;
|
||||||
protected String labelId;
|
protected String labelId;
|
||||||
|
protected String proxy;
|
||||||
protected Map<String, String> urls = new HashMap<String, String>(8, 10f);
|
protected Map<String, String> urls = new HashMap<String, String>(8, 10f);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct
|
* Construct
|
||||||
*
|
*
|
||||||
@@ -134,7 +179,20 @@ public class OpenSearchConfigElement extends ConfigElementAdapter
|
|||||||
this.label = label;
|
this.label = label;
|
||||||
this.labelId = labelId;
|
this.labelId = labelId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct
|
||||||
|
*
|
||||||
|
* @param label
|
||||||
|
* @param labelId
|
||||||
|
* @param proxy
|
||||||
|
*/
|
||||||
|
public EngineConfig(String label, String labelId, String proxy)
|
||||||
|
{
|
||||||
|
this(label, labelId);
|
||||||
|
this.proxy = proxy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return I18N label id
|
* @return I18N label id
|
||||||
*/
|
*/
|
||||||
@@ -151,6 +209,14 @@ public class OpenSearchConfigElement extends ConfigElementAdapter
|
|||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return proxy
|
||||||
|
*/
|
||||||
|
public String getProxy()
|
||||||
|
{
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the urls supported by this engine
|
* Gets the urls supported by this engine
|
||||||
*
|
*
|
||||||
@@ -171,17 +237,39 @@ public class OpenSearchConfigElement extends ConfigElementAdapter
|
|||||||
this.urls.put(mimetype, uri);
|
this.urls.put(mimetype, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inner class representing the configuration of the OpenSearch proxy
|
||||||
|
*
|
||||||
|
* @author davidc
|
||||||
|
*/
|
||||||
|
public static class ProxyConfig
|
||||||
|
{
|
||||||
|
protected String url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see java.lang.Object#toString()
|
* Construct
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
*/
|
*/
|
||||||
@Override
|
public ProxyConfig(String url)
|
||||||
public String toString()
|
|
||||||
{
|
{
|
||||||
StringBuilder buffer = new StringBuilder(super.toString());
|
if (url == null || url.length() == 0)
|
||||||
buffer.append(" {label=").append(this.label);
|
{
|
||||||
buffer.append(" labelId=").append(this.labelId).append(")");
|
throw new IllegalArgumentException("'url' must be specified");
|
||||||
return buffer.toString();
|
}
|
||||||
}
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return url
|
||||||
|
*/
|
||||||
|
public String getUrl()
|
||||||
|
{
|
||||||
|
return url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ import org.alfresco.config.ConfigElement;
|
|||||||
import org.alfresco.config.ConfigException;
|
import org.alfresco.config.ConfigException;
|
||||||
import org.alfresco.config.xml.elementreader.ConfigElementReader;
|
import org.alfresco.config.xml.elementreader.ConfigElementReader;
|
||||||
import org.alfresco.web.config.OpenSearchConfigElement.EngineConfig;
|
import org.alfresco.web.config.OpenSearchConfigElement.EngineConfig;
|
||||||
|
import org.alfresco.web.config.OpenSearchConfigElement.ProxyConfig;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
|
||||||
@@ -37,9 +38,11 @@ public class OpenSearchElementReader implements ConfigElementReader
|
|||||||
public static final String ELEMENT_ENGINES = "engines";
|
public static final String ELEMENT_ENGINES = "engines";
|
||||||
public static final String ELEMENT_ENGINE = "engine";
|
public static final String ELEMENT_ENGINE = "engine";
|
||||||
public static final String ELEMENT_URL = "url";
|
public static final String ELEMENT_URL = "url";
|
||||||
|
public static final String ELEMENT_PROXY = "proxy";
|
||||||
public static final String ATTR_TYPE = "type";
|
public static final String ATTR_TYPE = "type";
|
||||||
public static final String ATTR_LABEL = "label";
|
public static final String ATTR_LABEL = "label";
|
||||||
public static final String ATTR_LABEL_ID = "label-id";
|
public static final String ATTR_LABEL_ID = "label-id";
|
||||||
|
public static final String ATTR_PROXY = "proxy";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,7 +74,8 @@ public class OpenSearchElementReader implements ConfigElementReader
|
|||||||
Element engineElem = engines.next();
|
Element engineElem = engines.next();
|
||||||
String label = engineElem.attributeValue(ATTR_LABEL);
|
String label = engineElem.attributeValue(ATTR_LABEL);
|
||||||
String labelId = engineElem.attributeValue(ATTR_LABEL_ID);
|
String labelId = engineElem.attributeValue(ATTR_LABEL_ID);
|
||||||
EngineConfig engineCfg = new EngineConfig(label, labelId);
|
String proxy = engineElem.attributeValue(ATTR_PROXY);
|
||||||
|
EngineConfig engineCfg = new EngineConfig(label, labelId, proxy);
|
||||||
|
|
||||||
// construct urls for engine
|
// construct urls for engine
|
||||||
Iterator<Element> urlsConfig = engineElem.elementIterator(ELEMENT_URL);
|
Iterator<Element> urlsConfig = engineElem.elementIterator(ELEMENT_URL);
|
||||||
@@ -87,6 +91,20 @@ public class OpenSearchElementReader implements ConfigElementReader
|
|||||||
configElement.addEngine(engineCfg);
|
configElement.addEngine(engineCfg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extract proxy configuration
|
||||||
|
String url = null;
|
||||||
|
Element proxyElem = element.element(ELEMENT_PROXY);
|
||||||
|
if (proxyElem != null)
|
||||||
|
{
|
||||||
|
Element urlElem = proxyElem.element(ELEMENT_URL);
|
||||||
|
if (urlElem != null)
|
||||||
|
{
|
||||||
|
url = urlElem.getTextTrim();
|
||||||
|
ProxyConfig proxyCfg = new ProxyConfig(url);
|
||||||
|
configElement.setProxy(proxyCfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return configElement;
|
return configElement;
|
||||||
|
@@ -12,6 +12,7 @@ import javax.faces.context.ResponseWriter;
|
|||||||
import org.alfresco.config.Config;
|
import org.alfresco.config.Config;
|
||||||
import org.alfresco.config.ConfigService;
|
import org.alfresco.config.ConfigService;
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.web.api.services.SearchProxy;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.config.OpenSearchConfigElement;
|
import org.alfresco.web.config.OpenSearchConfigElement;
|
||||||
import org.alfresco.web.config.OpenSearchConfigElement.EngineConfig;
|
import org.alfresco.web.config.OpenSearchConfigElement.EngineConfig;
|
||||||
@@ -28,7 +29,6 @@ import org.springframework.web.jsf.FacesContextUtils;
|
|||||||
public class UIOpenSearch extends SelfRenderingComponent
|
public class UIOpenSearch extends SelfRenderingComponent
|
||||||
{
|
{
|
||||||
protected final static String SCRIPTS_WRITTEN = "_alfOpenSearchScripts";
|
protected final static String SCRIPTS_WRITTEN = "_alfOpenSearchScripts";
|
||||||
protected final static String ATOM_TYPE = "application/atom+xml";
|
|
||||||
protected final static String ENGINE_ID_PREFIX = "eng";
|
protected final static String ENGINE_ID_PREFIX = "eng";
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
@@ -205,6 +205,8 @@ public class UIOpenSearch extends SelfRenderingComponent
|
|||||||
// get the web api config service object from spring
|
// get the web api config service object from spring
|
||||||
ConfigService cfgSvc = (ConfigService)FacesContextUtils.
|
ConfigService cfgSvc = (ConfigService)FacesContextUtils.
|
||||||
getRequiredWebApplicationContext(context).getBean("web.api.Config");
|
getRequiredWebApplicationContext(context).getBean("web.api.Config");
|
||||||
|
SearchProxy searchProxy = (SearchProxy)FacesContextUtils.
|
||||||
|
getRequiredWebApplicationContext(context).getBean("web.api.SearchProxy");
|
||||||
if (cfgSvc != null)
|
if (cfgSvc != null)
|
||||||
{
|
{
|
||||||
// get the OpenSearch configuration
|
// get the OpenSearch configuration
|
||||||
@@ -229,11 +231,10 @@ public class UIOpenSearch extends SelfRenderingComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
// locate search engine template url of most appropriate response type
|
// locate search engine template url of most appropriate response type
|
||||||
Map<String, String> urls = engineCfg.getUrls();
|
String url = searchProxy.createUrl(engineCfg, MimetypeMap.MIMETYPE_ATOM);
|
||||||
String url = urls.get(MimetypeMap.MIMETYPE_ATOM);
|
|
||||||
if (url == null)
|
if (url == null)
|
||||||
{
|
{
|
||||||
url = urls.get(MimetypeMap.MIMETYPE_RSS);
|
url = searchProxy.createUrl(engineCfg, MimetypeMap.MIMETYPE_RSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url != null)
|
if (url != null)
|
||||||
|
@@ -245,6 +245,11 @@
|
|||||||
<servlet-name>apiServlet</servlet-name>
|
<servlet-name>apiServlet</servlet-name>
|
||||||
<servlet-class>org.alfresco.web.api.APIServlet</servlet-class>
|
<servlet-class>org.alfresco.web.api.APIServlet</servlet-class>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>proxyServlet</servlet-name>
|
||||||
|
<servlet-class>org.alfresco.web.app.servlet.HTTPProxyServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>workflowDefinitionImageServlet</servlet-name>
|
<servlet-name>workflowDefinitionImageServlet</servlet-name>
|
||||||
@@ -321,6 +326,11 @@
|
|||||||
<url-pattern>/service/*</url-pattern>
|
<url-pattern>/service/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>proxyServlet</servlet-name>
|
||||||
|
<url-pattern>/proxy</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>JBPMDeployProcessServlet</servlet-name>
|
<servlet-name>JBPMDeployProcessServlet</servlet-name>
|
||||||
<url-pattern>/jbpm/deployprocess</url-pattern>
|
<url-pattern>/jbpm/deployprocess</url-pattern>
|
||||||
|
Reference in New Issue
Block a user