You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by su...@apache.org on 2011/12/07 16:41:45 UTC

svn commit: r1211477 [4/4] - in /incubator/stanbol/trunk: cmsadapter/cmis/src/main/java/org/apache/stanbol/cmsadapter/cmis/mapping/ cmsadapter/jcr/src/main/java/org/apache/stanbol/cmsadapter/jcr/mapping/ contenthub/ contenthub/api/src/main/java/org/apa...

Modified: incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/resources/SearchResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/resources/SearchResource.java?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/resources/SearchResource.java (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/resources/SearchResource.java Wed Dec  7 15:41:42 2011
@@ -17,8 +17,9 @@
 
 package org.apache.stanbol.contenthub.web.resources;
 
-import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -32,6 +33,7 @@ import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
@@ -49,10 +51,11 @@ import org.apache.solr.common.SolrDocume
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.stanbol.commons.solr.IndexReference;
 import org.apache.stanbol.commons.solr.RegisteredSolrServerTracker;
-import org.apache.stanbol.commons.solr.managed.IndexMetadata;
 import org.apache.stanbol.commons.solr.managed.ManagedSolrServer;
 import org.apache.stanbol.commons.web.base.ContextHelper;
 import org.apache.stanbol.commons.web.base.resource.BaseStanbolResource;
+import org.apache.stanbol.contenthub.core.utils.EntityHubClient;
+import org.apache.stanbol.contenthub.core.utils.ExploreHelper;
 import org.apache.stanbol.contenthub.core.utils.JSONUtils;
 import org.apache.stanbol.contenthub.core.utils.SearchUtils;
 import org.apache.stanbol.contenthub.servicesapi.search.Search;
@@ -71,6 +74,7 @@ import org.osgi.framework.InvalidSyntaxE
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.hp.hpl.jena.ontology.OntModel;
 import com.sun.jersey.api.view.Viewable;
 
 /**
@@ -88,8 +92,9 @@ public class SearchResource extends Base
     private TcManager tcManager;
     private Object templateData = null;
     private Object facets = null;
+    private Object suggestions = null;
 
-    private ManagedSolrServer solrDirectoryManager;
+    private ManagedSolrServer managedSolrServer;
 
     private SolrServer solrServer;
 
@@ -97,16 +102,15 @@ public class SearchResource extends Base
         searcher = ContextHelper.getServiceFromContext(Search.class, context);
         tcManager = ContextHelper.getServiceFromContext(TcManager.class, context);
         processor = ContextHelper.getServiceFromContext(SearchProcessor.class, context);
-        solrDirectoryManager = ContextHelper.getServiceFromContext(ManagedSolrServer.class, context);
+        managedSolrServer = ContextHelper.getServiceFromContext(ManagedSolrServer.class, context);
         BundleContext bundleContext = ContextHelper.getBundleContext(context);
-        if (solrDirectoryManager != null) {
-            if (!solrDirectoryManager.isManagedIndex("contenthub")) {
-                solrDirectoryManager.createSolrIndex("contenthub", "contenthub", null);
-            }
-            RegisteredSolrServerTracker tracker = new RegisteredSolrServerTracker(
-                bundleContext, new IndexReference(
-                    solrDirectoryManager.getServerName(), "contenthub"));
-            //TODO: this is currently done for each request
+        if (managedSolrServer != null) {
+            if (!managedSolrServer.isManagedIndex("contenthub")) {
+                managedSolrServer.createSolrIndex("contenthub", "contenthub", null);
+            }
+            RegisteredSolrServerTracker tracker = new RegisteredSolrServerTracker(bundleContext,
+                    new IndexReference(managedSolrServer.getServerName(), "contenthub"));
+            // TODO: this is currently done for each request
             tracker.open();
             solrServer = tracker.getService();
             tracker.close();
@@ -115,28 +119,54 @@ public class SearchResource extends Base
 
     @GET
     @Produces(MediaType.TEXT_HTML)
-    public final Response get() {
+    public final Response get(@QueryParam("kw") String keywords) {
         try {
-            SearchInfo si = new SearchInfo();
-            Set<UriRef> mGraphs = tcManager.listMGraphs();
-            Iterator<UriRef> it = mGraphs.iterator();
-            while (it.hasNext()) {
-                String graphURI = it.next().getUnicodeString();
-                if (SearchUtils.isGraphReserved(graphURI)) continue;
-                si.getOntologies().add(graphURI);
-            }
-
-            for (SearchEngine engine : processor.listEngines()) {
-                si.getEngines().add(new EngineInfo(engine.toString(), engine.getClass().getCanonicalName()));
+            if (keywords != null && keywords.length() > 0) {
+                String[] keywordArray = getKeywordArray(keywords);
+                List<String> allowedEngines = new ArrayList<String>();
+                for (SearchEngine engine : processor.listEngines()) {
+                    allowedEngines.add(engine.toString());
+                }
+                SearchContext searchContext = (SearchContext) searcher.search(keywordArray, null,
+                    allowedEngines, null);
+                this.facets = getConstraints(searchContext);
+                this.templateData = new TempSearchResult(searchContext);
+                return Response.ok(new Viewable("result_full", this)).build();
+            } else {
+                SearchInfo si = new SearchInfo();
+                Set<UriRef> mGraphs = tcManager.listMGraphs();
+                Iterator<UriRef> it = mGraphs.iterator();
+                while (it.hasNext()) {
+                    String graphURI = it.next().getUnicodeString();
+                    if (SearchUtils.isGraphReserved(graphURI)) continue;
+                    si.getOntologies().add(graphURI);
+                }
+
+                for (SearchEngine engine : processor.listEngines()) {
+                    si.getEngines().add(
+                        new EngineInfo(engine.toString(), engine.getClass().getCanonicalName()));
+                }
+                this.templateData = si;
+                return Response.ok(new Viewable("index", this), MediaType.TEXT_HTML).build();
             }
-            this.templateData = si;
-            return Response.ok(new Viewable("index", this), MediaType.TEXT_HTML).build();
 
         } catch (Exception e) {
             throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
         }
     }
 
+    private String[] getKeywordArray(String keywords) {
+        String[] keywordArray = null;
+        if (keywords.startsWith("\"") && keywords.endsWith("\"")) {
+            keywordArray = new String[1];
+            keywordArray[0] = keywords;
+        } else {
+            // Separate the keywords only by space character.
+            keywordArray = keywords.split(" ");
+        }
+        return keywordArray;
+    }
+
     @POST
     @Produces(MediaType.TEXT_HTML)
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@@ -149,14 +179,7 @@ public class SearchResource extends Base
                                                                            SolrServerException,
                                                                            IOException {
         Map<String,List<Object>> facetMap = JSONUtils.convertToMap(jsonCons);
-        String[] keywordArray = null;
-        if (keywords.startsWith("\"") && keywords.endsWith("\"")) {
-            keywordArray = new String[1];
-            keywordArray[0] = keywords;
-        } else {
-            // Separate the keywords only by space character.
-            keywordArray = keywords.split(" ");
-        }
+        String[] keywordArray = getKeywordArray(keywords);
 
         // FIXME A better implementation should be used instead of this casting.
         SearchContext searchContext = (SearchContext) searcher.search(keywordArray, graphURI, engines,
@@ -166,6 +189,15 @@ public class SearchResource extends Base
         return Response.ok(new Viewable("result", this)).build();
     }
 
+    @POST
+    @Produces(MediaType.TEXT_HTML)
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @Path("/suggestion")
+    public final Response explorer(@FormParam("keyword") String keyword) {
+        this.suggestions = exploreFromKeyword(keyword);
+        return Response.ok(new Viewable("suggestionResult", this)).build();
+    }
+
     private Object getConstraints(SearchContext sc) throws InstantiationException,
                                                    IllegalAccessException,
                                                    SolrServerException,
@@ -202,14 +234,15 @@ public class SearchResource extends Base
         }
         solrQuery.setFacet(true);
         for (String field : fields) {
-            if (!SolrFieldName.isNameReserved(field) && !SolrVocabulary.isNameExcluded(field)) {
+            if (SolrFieldName.CREATIONDATE.toString().equals(field)
+                || (!SolrFieldName.isNameReserved(field) && !SolrVocabulary.isNameExcluded(field))) {
                 solrQuery.addFacetField(field);
             }
         }
         solrQuery.setRows(0);
 
         QueryResponse result = solrServer.query(solrQuery);
-        List<FacetField> facets = result.getFacetFields();
+        List<FacetField> facets = bringAnnotatedFacetsForward(result.getFacetFields());
         logger.debug(facets.toString());
         return facets;
     }
@@ -222,22 +255,57 @@ public class SearchResource extends Base
         return facets;
     }
 
+    public Object getSuggestions() {
+        return suggestions;
+    }
+
     // TODO: This method SHOULD be written again, maybe as a SEPERATE class
     /**
      * this method is written just to see that we can explore from search keyword using entityhub
      * 
      * @param queryKeywords
      *            is the all keywords seperated by " " that has been entered in search interface
-     * @return is the List of all related entity names
-     */
-    /*
-     * public void exploreFromKeyword(String queryKeywords) { EntityHubClient ehc =
-     * EntityHubClient.getInstance("http://localhost:8080/entityhub"); String keyword =
-     * queryKeywords.replaceAll(" ","_"); List<String> types = new ArrayList<String>();
-     * 
-     * OntModel resultModel = ehc.referencedSiteFind(keyword, "en"); if(resultModel != null) { ExploreHelper
-     * explorer = new ExploreHelper(resultModel);
-     * 
-     * Map<String, List<String>> resultMap = explorer.getSuggestedKeywords(); } }
+     * @return is the List of all related entity names, returns null if there is no element in hashmap
      */
+    private Map<String,Set<String>> exploreFromKeyword(String queryKeywords) {
+        Map<String,Set<String>> resultMap = new HashMap<String,Set<String>>();
+        EntityHubClient ehc = EntityHubClient.getInstance(uriInfo.getBaseUri().toString() + "entityhub");
+        String keyword = queryKeywords.replaceAll(" ", "_");
+
+        OntModel resultModel = ehc.referencedSiteFind(keyword, "en");
+        if (resultModel != null) {
+            ExploreHelper explorer = new ExploreHelper(resultModel);
+
+            resultMap = explorer.getSuggestedKeywords();
+
+        }
+
+        return resultMap;
+    }
+
+    private List<FacetField> bringAnnotatedFacetsForward(List<FacetField> facets) {
+        List<FacetField> annotatedEntityFacets = new ArrayList<FacetField>();
+        for (FacetField ff : facets) {
+            String facetName = ff.getName();
+            if (isAnnotatedEntityFacet(facetName)) {
+                annotatedEntityFacets.add(ff);
+            }
+        }
+        for (FacetField ff : annotatedEntityFacets) {
+            facets.remove(ff);
+        }
+        for (FacetField ff : annotatedEntityFacets) {
+            facets.add(0, ff);
+        }
+        return facets;
+    }
+
+    private boolean isAnnotatedEntityFacet(String facetName) {
+        for (SolrFieldName sfn : SolrFieldName.getAnnotatedEntityFieldNames()) {
+            if (sfn.toString().equals(facetName)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }

Modified: incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/search/model/TempSearchResult.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/search/model/TempSearchResult.java?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/search/model/TempSearchResult.java (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/search/model/TempSearchResult.java Wed Dec  7 15:41:42 2011
@@ -17,7 +17,10 @@
 
 package org.apache.stanbol.contenthub.web.search.model;
 
+import java.util.List;
+
 import org.apache.stanbol.contenthub.core.utils.JSONUtils;
+import org.apache.stanbol.contenthub.servicesapi.search.execution.QueryKeyword;
 import org.apache.stanbol.contenthub.servicesapi.search.execution.SearchContext;
 
 /**
@@ -42,4 +45,17 @@ public class TempSearchResult {
     public String getConstraints() {
         return JSONUtils.convertToString(context.getConstraints());
     }
+    
+    public String getKeywords() {
+        StringBuilder sb = new StringBuilder();
+        for(QueryKeyword kw : context.getQueryKeyWords()) {
+            sb.append(kw.getKeyword());
+            sb.append(" ");
+        }
+        return sb.toString();
+    }
+    
+    public List<String> getEngines() {
+        return context.getAllowedEngines();
+    }
 }

Modified: incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/search/model/TopicNews.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/search/model/TopicNews.java?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/search/model/TopicNews.java (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/java/org/apache/stanbol/contenthub/web/search/model/TopicNews.java Wed Dec  7 15:41:42 2011
@@ -29,7 +29,8 @@ public class TopicNews {
 
     private String topic;
     private List<URI> uris;
-
+    private List<String> titles;
+    
     public String getTopic() {
         return topic;
     }
@@ -38,6 +39,10 @@ public class TopicNews {
         return uris;
     }
 
+    public List<String> getTitles() {
+        return titles;
+    }
+    
     public void setTopic(String topic) {
         this.topic = topic;
     }
@@ -45,4 +50,8 @@ public class TopicNews {
     public void setUris(List<URI> uris) {
         this.uris = uris;
     }
+    
+    public void setTitles(List<String> titles) {
+        this.titles = titles;
+    }
 }

Modified: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/static/style/search.css
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/static/style/search.css?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/static/style/search.css (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/static/style/search.css Wed Dec  7 15:41:42 2011
@@ -50,13 +50,21 @@ div .keywords{
   width: 30%;
 }
 
-div #facets{
+div .chosenfacets{
   display: inline-block;
   position: relative;
   left: 1%;
   width: 30%;
 }
 
+div .facets{
+  display: inline-block;
+  position: relative;
+  left: 1%;
+  width: 30%;
+  float: left;
+}
+
 div .resources{
   display: inline-block;
   position: relative;
@@ -64,6 +72,16 @@ div .resources{
   float: right;
 }
 
+div .searchbox {
+  position: absolute;
+  top: 15%;
+  left: 65%;
+  margin-left: 0.5em;
+  border: 1px solid transparent;
+  padding: 0.5em 0.5em 0.5em 0.5em;
+  border-radius: 8px;
+}
+
 H3.ui-accordion-header{
   padding-left: 2em;
 }
@@ -87,4 +105,10 @@ H3.ui-accordion-header{
 	padding-left: 23px;
 	margin-top: 0px;
 	margin-bottom: 0px;
+}
+
+.facetText{
+	width: 72px;
+	font-size: 12px;
+	color: #C43187;
 }
\ No newline at end of file

Added: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/facetResultMacro.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/facetResultMacro.ftl?rev=1211477&view=auto
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/facetResultMacro.ftl (added)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/facetResultMacro.ftl Wed Dec  7 15:41:42 2011
@@ -0,0 +1,79 @@
+<#macro facetResultMacro facetField consLink>
+	<#assign limit=4 />
+	<#if facetField?exists>
+		<#if facetField.values?exists && facetField.values?size != 0>
+			<#if facetField.name == "stanbolreserved_creationdate">
+				<#assign facetName=facetField.name?substring(facetField.name?index_of("_")+1,facetField.name?length)/>
+				${facetName}
+				<br/>
+				<#assign orderedList = facetField.values?sort_by("name") />
+				<ul><li>
+					<input id="dateFrom" class="facetText" type="text" value="${orderedList[0].name?substring(0,10)}" readonly="true"/> 
+					to <input id="dateTo" class="facetText" type="text" value="${orderedList[orderedList?size-1].name?substring(0,10)}" readonly="true"/>
+					<#assign consLinkEscaped = consLink?url("UTF-8")?js_string/>
+					<a href="javascript:getResults('${consLinkEscaped}','stanbolreserved_creationdate','','date')"><input type="button" value=">" /></a>
+				</li></ul>
+			<#else>
+				<#assign facetName=facetField.name?substring(0,facetField.name?last_index_of("_"))/>
+				${facetName}
+				<ul id="${facetName}list">
+					<#if facetField.name?ends_with("_l")>
+						<li>
+							<input id="${facetField.name}TextMin" class="facetText" type="text"/> 
+							to <input id="${facetField.name}TextMax" class="facetText" type="text"/>
+							<#assign facetNameEscaped = facetField.name?url("UTF-8")?js_string/>
+							<#assign consLinkEscaped = consLink?url("UTF-8")?js_string/>
+							<a href="javascript:getResults('${consLinkEscaped}','${facetNameEscaped}','','range')"><input type="button" value=">" /></a>
+						</li>
+					</#if>
+					
+					<#assign x=0 />
+					<#list facetField.values as count>
+						<#assign facetNameEscaped = facetField.name?url("UTF-8")?js_string/>
+						<#assign countNameEscaped = count.name?url("UTF-8")?js_string/>
+						<#assign consLinkEscaped = consLink?url("UTF-8")?js_string/>
+						<#if x = limit><#break/></#if>
+						<li><a href=javascript:getResults('${consLinkEscaped}','${facetNameEscaped}','${countNameEscaped}','addFacet')>${count.name} ( ${count.count} )</a></li>
+						<#assign x=x+1 />
+					</#list>
+				</ul>						
+				<#if facetField.values?size &gt; limit>
+					<a id="${facetName?replace(':','_')}" href="">more</a><br>
+				</#if>
+			</#if>
+		</#if>
+	<#else>
+		<p>No results found<p>
+	</#if>
+	<script type=text/javascript>
+	
+	
+	
+	function registersSparqlHandler() {
+	
+		$(document).ready(function(){
+			$("#dateFrom").datepicker({ dateFormat: 'yy-mm-dd' });
+			$("#dateTo").datepicker({ dateFormat: 'yy-mm-dd' });
+		});
+	
+	   $("#${facetName?replace(':','_')}", this).click(function(e) {
+	     // disable regular form click
+	     e.preventDefault();
+	     if(document.getElementById("${facetName?replace(':','_')}").innerHTML == "more")
+	     {
+	     	var a="<#list facetField.values as count><#assign consLinkEscaped = consLink?url("UTF-8")?js_string/><#assign countNameEscaped = count.name?url("UTF-8")?js_string/><#assign facetNameEscaped = facetField.name?url("UTF-8")?js_string/><li><a href=javascript:getResults('${consLinkEscaped}','${facetNameEscaped}','${countNameEscaped}','addFacet')>${count.name} ( ${count.count} )</a></li></#list>";
+	     	document.getElementById("${facetName}list").innerHTML=a;
+	     	$(this).attr({ 'innerHTML': 'less' });
+		 }
+		 else
+		 {
+		 	var a="<#assign x=0 /><#list facetField.values as count><#if x = limit><#break/></#if><li><a href=javascript:getResults('${consLinkEscaped}','${facetNameEscaped}','${countNameEscaped}','addFacet')>${count.name} ( ${count.count} )</a></li><#assign x=x+1 /></#list>";
+		 	document.getElementById("${facetName}list").innerHTML=a;
+		 	$(this).attr({ 'innerHTML': 'more' });		 	
+		 }    
+	     });
+	 }
+	 
+	 $(document).ready(registersSparqlHandler);
+</script>
+</#macro>
\ No newline at end of file

Modified: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/keyword_result_tab.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/keyword_result_tab.ftl?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/keyword_result_tab.ftl (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/keyword_result_tab.ftl Wed Dec  7 15:41:42 2011
@@ -26,7 +26,7 @@
 		<#else>	
 			<#list qk.relatedDocumentResources?sort_by("scoreString")?reverse as docRes>
 				<div class="bordered-bottom">
-					<li class="lined"><a href="${it.publicBaseUri}contenthub/page/${docRes.localId}">${docRes.localId}</a></li>
+					<li class="lined"><a href="${it.publicBaseUri}contenthub/page/${docRes.localId}">${docRes.documentTitle}</a></li>
 					<a class="collapseItem lined" href="/">
 						<img  src="/static/home/images/foldable_folded.png"/>
 					</a>

Added: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/relatedKeywordMacro.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/relatedKeywordMacro.ftl?rev=1211477&view=auto
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/relatedKeywordMacro.ftl (added)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/relatedKeywordMacro.ftl Wed Dec  7 15:41:42 2011
@@ -0,0 +1,40 @@
+<#macro relatedKeywordMacro relatedKeywordList source>
+	<#assign limit = 4/>
+		Related ${source} Keywords
+		<ul id="${source}list" class="spadded">
+			<#assign x = 0/>
+			<#list relatedKeywordList as related>
+				<#assign relatedName = related.localName?replace(' ','_')>
+				<#if x == limit><#break/></#if>
+				<li><a href=javascript:getResults(null,null,"${relatedName}","explore")>${relatedName?replace('_',' ')}</a></li>
+				<#assign x = x + 1>
+			</#list>
+		</ul>
+		<#if relatedKeywordList?size &gt; limit>
+			<a id="${source}button" href="">more</a><br>
+		</#if>
+		<br/>
+		
+	<script language="javascript">
+		function moreLessButtonHandler() {
+		   $("#${source}button", this).click(function(e) {
+		     // disable regular form click
+		     e.preventDefault();
+		     if(document.getElementById("${source}button").innerHTML == "more")
+		     {
+		     	var a="<#list relatedKeywordList as related><#assign relatedName = related.localName?replace(' ','_')><li><a href=javascript:getResults(null,null,'${relatedName}','explore')>${relatedName?replace('_', ' ')}</a></li></#list>";
+		     	document.getElementById("${source}list").innerHTML=a;
+		     	$(this).attr({ 'innerHTML': 'less' });
+			 }
+			 else
+			 {
+			 	var a="<#assign x=0><#list relatedKeywordList as related><#assign relatedName = related.localName?replace('_',' ')><#if x == limit><#break/></#if><li><a href=javascript:getResults(null,null,'${relatedName}','explore')>${relatedName?replace('_', ' ')}</a></li><#assign x=x+1 /></#list>";
+			 	document.getElementById("${source}list").innerHTML=a;
+			 	$(this).attr({ 'innerHTML': 'more' });		 	
+			 }    
+		     });
+		 }		 
+		 
+		 $(document).ready(moreLessButtonHandler);
+	</script>
+</#macro>
\ No newline at end of file

Added: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/suggestedKeyword.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/suggestedKeyword.ftl?rev=1211477&view=auto
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/suggestedKeyword.ftl (added)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/imports/suggestedKeyword.ftl Wed Dec  7 15:41:42 2011
@@ -0,0 +1,41 @@
+<#macro suggestedKeyword set key>
+	<#assign limit = 4>
+		Related ${key}
+		<#assign relatedKey = "related"+key />
+		<ul id="${relatedKey}list" class="spadded">
+			<#assign x = 0/>
+			<#list set as related>
+				<#assign related = related?replace('_',' ')>
+				<#if x == limit><#break/></#if>
+				<li><a href=javascript:getResults(null,null,"${related}","explore")>${related}</a></li>
+				<#assign x = x + 1>
+			</#list>
+		</ul>
+		<#if set?size &gt; limit>
+			<a id="${relatedKey}" href="">more</a><br>
+		</#if>
+		<br>
+		
+	<script language="javascript">
+		function moreLessButtonHandler() {
+		   $("#${relatedKey}", this).click(function(e) {
+		     // disable regular form click
+		     e.preventDefault();
+		     if(document.getElementById("${relatedKey}").innerHTML == "more")
+		     {
+		     	var a="<#list set as related><#assign related = related?replace('_',' ')><li><a href=javascript:getResults(null,null,'${related}','explore')>${related?replace('_', ' ')}</a></li></#list>";
+		     	document.getElementById("${relatedKey}list").innerHTML=a;
+		     	$(this).attr({ 'innerHTML': 'less' });
+			 }
+			 else
+			 {
+			 	var a="<#assign x=0><#list set as related><#assign related = related?replace('_',' ')><#if x == limit><#break/></#if><li><a href=javascript:getResults(null,null,'${related}','explore')>${related?replace('_', ' ')}</a></li><#assign x=x+1 /></#list>";
+			 	document.getElementById("${relatedKey}list").innerHTML=a;
+			 	$(this).attr({ 'innerHTML': 'more' });		 	
+			 }    
+		     });
+		 }		 
+		 
+		 $(document).ready(moreLessButtonHandler);
+	</script>
+</#macro>
\ No newline at end of file

Modified: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/CNNImporterResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/CNNImporterResource/index.ftl?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/CNNImporterResource/index.ftl (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/CNNImporterResource/index.ftl Wed Dec  7 15:41:42 2011
@@ -43,9 +43,12 @@
 				<legend>Articles found for topic: ${it.templateData.topic}</legend>
 				<#if it.templateData.uris?exists && it.templateData.uris?size != 0>
 					<ul>
-					<#list it.templateData.uris as uri>
-						<li><a href="${uri}">${uri}</a></li>
-					</#list>
+					<#assign x=it.templateData.uris?size>
+					<#list 0..x-1 as i>
+						<#assign uri = it.templateData.uris[i]>
+						<#assign title = it.templateData.titles[i]/>
+						<li><a href="${it.publicBaseUri}contenthub/content/${uri}">${title}</a></li>
+					</#list>  
 					</ul>
 				<#else>
 					<p>No articles found for this topic<p>

Modified: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/ContenthubStoreResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/ContenthubStoreResource/index.ftl?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/ContenthubStoreResource/index.ftl (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/ContenthubStoreResource/index.ftl Wed Dec  7 15:41:42 2011
@@ -20,6 +20,13 @@
 
 <div class="panel" id="webview">
 
+<div class="searchbox">
+<table><tr><td>
+<input type="text" id="searchKeywords" name="searchKeywords" onkeydown="if (event.keyCode == 13) document.getElementById('searchButton').click()" /><input id="searchButton" type="button" value="Search" onclick="performSearch()" />
+</td></tr><tr align="right"><td>
+<div><a href="contenthub/search" />Search Page</a></div></td></tr></table>
+</div>
+
 <#--
 <em><strong>Disclaimer</strong>: this endpoint is a proof of concept /
 <strong>experimental</strong> feature. It does not actually store the content
@@ -34,17 +41,17 @@ on the disk, just in memory.</em>
 	<div>
 	  <tr>
 	  	<th></th>
-	    <th>Local ID</th>
+	    <th>Title</th>
 	    <th>Media type</th>
 	    <th>Enhancements <#--TODO: fix image path  <img src="${it.staticRootUrl}/contenthub/images/rdf.png" alt="Format: RDF"/> --></th>
 	  </tr>
 	  <#list it.recentlyEnhancedItems as item>
 	  <tr>
 		<td>
-			<img src="${it.staticRootUrl}/contenthub/images/edit_icon_16.png" onClick="javascript:editContentItem('${item.localId}');" title="Edit this item">
-			<img src="${it.staticRootUrl}/contenthub/images/delete_icon_16.png" onClick="javascript:deleteContentItem('${item.localId}');" title="Delete this item">
+			<img src="${it.staticRootUrl}/contenthub/images/edit_icon_16.png" onClick="javascript:editContentItem('${item.localId}');" title="Edit this item" />
+			<img src="${it.staticRootUrl}/contenthub/images/delete_icon_16.png" onClick="javascript:deleteContentItem('${item.localId}');" title="Delete this item" />
 		</td>
-	    <td><a href="${item.uri}" title="${item.uri}">${item.localId}</a></td>
+	    <td><a href="${item.uri}" title="${item.uri}">${item.title}</a></td>
 	    <td>${item.mimetype}</td>
 	    <td><a href="${it.publicBaseUri}contenthub/metadata/${item.localId}">${item.enhancements}</a></td>
 	  </tr>
@@ -66,61 +73,61 @@ on the disk, just in memory.</em>
 
 <div id="editingDiv"> </div>
 
-
 <h3>Submit Constraints to Content Item for analysis</h3>
 
 <fieldset>
 	<legend>Give Field:Value for your content</legend>
 	<div id="constraintsDiv" style="max-height:190px;overflow:auto">
 		<div id="textDiv1">
-			<br><input type="text" name="fieldText1"> : <input type="text" name="valueText1">
+			<br><input type="text" name="fieldText1" value="${it.titleFieldName}" readonly="readonly" /> : <input type="text" name="valueText1" />
 		</div>
 	</div>
 	
-	<br><label onClick="javascript:addConstraint();"><img src="${it.staticRootUrl}/contenthub/images/add_icon_16.png" />  Add a new constraint</label>
+	<br><label onClick="javascript:addConstraint(null);"><img src="${it.staticRootUrl}/contenthub/images/add_icon_16.png" />  Add a new constraint</label>
 </fieldset>
 
 <h3>Submit a new Content Item for analysis</h3>
 
-
-<form method="POST" accept-charset="utf-8">
+<form method="POST" accept-charset="utf-8" onSubmit = "return setConstraints();">
   <fieldset>
-  <input type="hidden" id="constraintsHidden" name="constraints" value="">
-  <input type="hidden" id="hiddenId" name="contentId" value="">
-  <legend>Submit raw text content</legend>
-  <p><textarea rows="15" id="contentTextArea" name="content"></textarea></p>
-  <p><input type="submit" onClick="javascript:setConstraints();" value="Submit text"></p>
+	  <input type="hidden" id="constraintsContent" name="constraints" value="" />
+	  <input type="hidden" id="idContent" name="contentId" value="" />
+	  <legend>Submit raw text content</legend>
+	  <p><textarea rows="15" id="contentTextArea" name="content"></textarea></p>
+	  <p><input type="submit" value="Submit text" /></p>
   </fieldset>
 </form>
 
-<form method="POST" accept-charset="utf-8">
+<form method="POST" accept-charset="utf-8" onSubmit = "return setConstraints();">
   <fieldset>
-  <input type="hidden" id="constraintsHidden" name="constraints" value="">
-  <input type="hidden" id="hiddenId" name="contentId" value="">
-  <legend>Submit a remote public resource by URL</legend>
-  <p><input name="url" type="text" class="url" />
-     <input type="submit" onClick="javascript:setConstraints();" value="Submit URL"></p>
+	  <input type="hidden" id="constraintsURL" name="constraints" value="" />
+	  <input type="hidden" id="idURL" name="contentId" value="" />
+	  <legend>Submit a remote public resource by URL</legend>
+	  <p>
+	  	<input name="url" type="text" class="url" />
+	  	<input type="submit" value="Submit URL" />
+	  </p>
   </fieldset>
 </form>
 
-<form method="POST" accept-charset="utf-8"  enctype="multipart/form-data">
+<form method="POST" accept-charset="utf-8"  enctype="multipart/form-data" onSubmit = "return setConstraints();">
   <fieldset>
-  <input type="hidden" id="constraintsHidden" name="constraints" value="">
-  <input type="hidden" id="hiddenId" name="contentId" value="">
-  <legend>Upload a local file</legend>
-  <p><input name="file" type="file"/>
-     <input type="submit" onClick="javascript:setConstraints();" value="Submit file"></p>
+	  <input type="hidden" id="constraintsFile" name="constraints" value="" />
+	  <input type="hidden" id="idFile" name="contentId" value="" />
+	  <legend>Upload a local file</legend>
+	  <p>
+	  	<input name="file" type="file"/>
+	  	<input type="submit" value="Submit file" />
+	  </p>
   </fieldset>
 </form>
-
-
 </div>
 
 <div class="panel" id="restapi" style="display: none;">
 <h3>Uploading new content to the Content Hub</h3>
 
   <p>You can upload content to the Content Hub for analysis with or without providing the content
-   id at your option:<p>
+   id at your option:</p>
   <ol>
     <li><code>PUT</code> content to <code>${it.publicBaseUri}contenthub/content/<strong>content-id</strong></code>
      with <code>Content-Type: text/plain</code>.</li>
@@ -168,7 +175,7 @@ Server: Jetty(6.1.x)
 
 <p>Once the content is created in the Content Hub, you can fetch back either the original content, a HTML summary view or
 the extracted RDF metadata by dereferencing the URL using the <code>Accept</code> header
-as selection switch:<p>
+as selection switch:</p>
 
 <pre>
 curl -i <strong>-H "Accept: text/plain"</strong> ${it.publicBaseUri}contenthub/content/sha1-84854eb6802a601ca2349ba28cc55f0b930ac96d
@@ -205,39 +212,55 @@ Server: Jetty(6.1.x)
 	function setConstraints(){
 		var i;
 		var result = JSON.parse("{}");
-		for(i=0 ; i<=counter ; i++){
+		for(i=1; i<=counter; i++){
 			if (document.getElementById("textDiv" + i)) {
 				var field = jQuery.trim(document.getElementsByName("fieldText"+i)[0].value);
-				var value = document.getElementsByName("valueText"+i)[0].value;
+				var value = jQuery.trim(document.getElementsByName("valueText"+i)[0].value);
+				if(i == 1 && !value) {
+					// control for the title input... it must exist
+					alert('You should enter title for your content');
+					return false;
+				}
+				if(!field || !value) {
+					continue;
+				}
 				
 				if(result[field] == null) {
 					result[field] = new Array();
 				}
 				var values = value.split(",");
-				for(j=0 ; j<values.length ; j++){
+				for(j=0; j<values.length; j++){
 					result[field].push(jQuery.trim(values[j]));
 				}
 			}
 		}
-		document.getElementById("constraintsHidden").value = JSON.stringify(result);	
+		var constraints = document.getElementsByName('constraints');
+		for (var i in constraints) {
+			constraints[i].value = JSON.stringify(result);
+		}
+		return true;
 	}
 	
-	function addConstraint(){
+	function addConstraint(vfn){
 		counter++;
 		var newCons = document.createElement('div');
 		newCons.setAttribute('id','textDiv' + counter);
 		var fieldName = "fieldText"+counter;
 		var valueName = "valueText"+counter;
 		var url = "javascript:removeConstraint(" + counter + ");";
-		newCons.innerHTML = "<br><input type='text' name=" + fieldName + ">" 
+		if(vfn == '${it.titleFieldName}') {
+			newCons.innerHTML = "<br/><input type='text' name=" + fieldName + " readonly=\"readonly\" />" 
+		 					+ " : "
+		 					+ "<input type='text' name=" + valueName + " />";
+		}
+		else {
+			newCons.innerHTML = "<br/><input type='text' name=" + fieldName + " />" 
 		 					+ " : "
-		 					+ "<input type='text' name=" + valueName + ">"
-		 					+ "  <img src='${it.staticRootUrl}/contenthub/images/delete_icon_16.png' title='Remove' onClick=" + url + ">";
-		 		
+		 					+ "<input type='text' name=" + valueName + " />"
+		 					+ "  <img src='${it.staticRootUrl}/contenthub/images/delete_icon_16.png' title='Remove' onClick=" + url + " />";
+		}		 		
 		document.getElementById("constraintsDiv").appendChild(newCons);
-		
 		document.getElementsByName(fieldName)[0].focus();
-		
 	}
 	
 	function removeConstraint(divNo){
@@ -246,7 +269,10 @@ Server: Jetty(6.1.x)
 	}
 
 	function cancelEditing(){
-		document.getElementById("hiddenId").value = "";
+		var contentids = document.getElementsByName('contentId');
+		for (var i in contentids) {
+			contentids[i].value = "";
+		}
 		document.getElementById("editingDiv").innerHTML = "";
 	}
 
@@ -261,22 +287,35 @@ Server: Jetty(6.1.x)
 			cache: false,
 			success: function(jsonCons) {
 			
-				var JSONObject = JSON.parse(jsonCons);
+				var contentItem = JSON.parse(jsonCons);
 				var count=1;
-				if(JSONObject != null) {
-					document.getElementById("contentTextArea").value = JSONObject["content"];
-					document.getElementById("hiddenId").value = JSONObject["id"];
-					document.getElementById("editingDiv").innerHTML = 	'<img src="${it.staticRootUrl}/contenthub/images/delete_icon_16.png" title="Cancel Editing" onClick="javascript:cancelEditing()">'
-																		+"You are editing Content Item "+JSONObject["id"];
-					delete JSONObject["content"];
-					delete JSONObject["id"];
+				if(contentItem != null) {
+					// TODO: use more mimeType
+					if(contentItem["mimeType"] == "text/plain"){
+						document.getElementById("contentTextArea").value = contentItem["content"];
+					} else {
+						document.getElementById("contentTextArea").value = "";
+					}
+					var contentids = document.getElementsByName('contentId');
+					for (var i in contentids) {
+						contentids[i].value = contentItem["id"];
+					}
+					document.getElementById("editingDiv").innerHTML = 	'<img src="${it.staticRootUrl}/contenthub/images/delete_icon_16.png" title="Cancel Editing" onClick="javascript:cancelEditing()" />'
+																		+ " You are editing Content Item " + contentItem["id"];
+					delete contentItem["content"];
+					delete contentItem["id"];
+					delete contentItem["mimeType"];
 					
-					for(var p in JSONObject) {
-						if(JSONObject.hasOwnProperty(p)) {
-							var lastindex = p.toString().lastIndexOf("_");	
-							addConstraint();
-							document.getElementsByName("fieldText"+counter)[0].value = p.toString().substring(0, lastindex);
-							document.getElementsByName("valueText"+counter)[0].value = JSONObject[p].substring(1, JSONObject[p].length-1);
+					for(var p in contentItem) {
+						if(contentItem.hasOwnProperty(p)) {
+							var fieldName = p.toString();
+							if(fieldName.indexOf("_") != -1) {
+								var lastindex = fieldName.lastIndexOf("_");
+								fieldName = fieldName.substring(0, lastindex);
+							}
+							addConstraint(fieldName);
+							document.getElementsByName("fieldText"+counter)[0].value = fieldName;
+							document.getElementsByName("valueText"+counter)[0].value = contentItem[p].substring(1, contentItem[p].length-1);
 						}
 					}
 				}	
@@ -303,6 +342,11 @@ Server: Jetty(6.1.x)
 		});
 	}
 	
+	function performSearch() {
+		var lurl = "${it.publicBaseUri}contenthub/search?kw=" + $("#searchKeywords").val();
+		window.location.replace(lurl);
+	}
+	
 </script>
 </...@common.page>
 </#escape>

Modified: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/index.ftl?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/index.ftl (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/index.ftl Wed Dec  7 15:41:42 2011
@@ -18,16 +18,17 @@
 <#escape x as x?html>
 <@common.page title="Search" hasrestapi=false>
 	<div id="search">
-		<form method="POST" accept="text/html" accept-charset="utf-8">
+	<#-- this feildset was normally in a form, ajax is used to do the post, dont need to use fom -->
 			<fieldset>
 				<legend>Keyword Based Search</legend>
 				<p>
-					Keywords: <input id="keywordIn" name="topic" type="text"/><br/>
+					Keywords: <input id="keywordIn" name="topic" type="text" onkeydown="if (event.keyCode == 13) document.getElementById('submitIn').click()"/><br/>
 				</p>
 				<p>
 					<!-- Ontology selection combobox-->
 					<#if it.templateData.ontologies?exists && it.templateData.ontologies?size != 0>
 					Graph: <select  id="graphIn" name="max" type="text" value="5">
+						<option value="choose_ontology">Choose an ontology</option>
 						<#list it.templateData.ontologies as ont>
 							<option value="${ont}">${ont}</option>
 						</#list>
@@ -53,18 +54,24 @@
 						</#if>
 					</fieldset>
 					<p>
-						<input id="submitIn" type="submit" value="Search"></input>
+						<input id="submitIn" type="button" value="Search" onclick="getResults(null,null,null,'first');"></input>
 					</p>
 					<img id="busyIcon" class="invisible centerImage" src="${it.staticRootUrl}/contenthub/images/ajax-loader.gif"/>
 			</fieldset>
-		</form>
 	</div>	
 	
 	<div id="resultContainer" class="invisible">
+		<div class="invisible" id="previousSuggestionButton"></div>
 		<div>
 			<!-- To be populated with ajax without xml :)-->
 		</div>
 	</div>
+	
+	<!-- To be populated by the second ajax for the suggestions div -->
+	<div id="tempEntityHubSuggestions" class="invisible"></div>
+	
+	<!-- to be populated by the list of suggested keywords to be able to get back in search -->
+	<div id="suggestedKeywordList" class="invisible">{"keywords":[]}</div>	
 	<!-- FIXME put a textarea so jQuery-ui tabs does not expand through footer -->
 	<textarea type="text" disabled="true" style="border-color: #fff; background: white; height:100px; max-height:100px; width:100%; max-width:100%"></textarea>
 	
@@ -72,57 +79,6 @@
 	
 		function init() {
 		
-			$("#submitIn", this).click(function(e) {
-				// disable regular form click
-				e.preventDefault();
-	     
-				//accumulate all selected engines in an array
-				var engines_selected = [];
-				$(".searchengine ").each(function(){
-				
-					if($(this).attr("checked")){
-						engines_selected.push($(this).val());
-					}	
-				});
-	
-				var graph_selected = $("#graphIn option:selected").val();
-		     
-				//make text area invisible
-				$("#searchResult").fadeOut(100);
-				$("#resultContainer").fadeOut(100);
-				//show busy icon
-				$("#busyIcon").removeClass("invisible");
-		     
-				$.ajax({
-					type : "POST",
-					async: true,
-					data: {keywords: $("#keywordIn").val(), graph: graph_selected, engines: engines_selected},
-					dataType: "html",
-					cache: false,
-					success: function(result) {
-						// since post does not create any resource, there is no possibility to redirect
-						$("#busyIcon").addClass("invisible");
-						$("#search").addClass("invisible");
-		       	 
-						$("#resultContainer > div").replaceWith(result.substr(result.indexOf("</div>")));
-						$(".keywords").accordion({collapsible: true, autoHeight: false });
-						$(".keywords").removeClass("ui-widget");
-						$(".resources > div").tabs({fx: { height: 'toggle', opacity: 'toggle' } });
-						$("#resultContainer").fadeIn("slow");
-		       	 
-						//collapsible content
-						$(".collapseItem").click(function(e){
-							e.preventDefault();
-							$(this).next(".collapseContent").slideToggle(500);
-						}); 
-					},
-					error: function(result) {
-						$("#busyIcon").addClass("invisible");
-						alert(result.status + ' ' + result.statusText);
-					}
-				});
-			});
-	   
 			//accordion
 			$(".keywords").accordion({collapsible: true});
 		}
@@ -137,20 +93,120 @@
 		}
 		
 
-		function getResults(jsonCons,facetName,facetValue){
-
-			var JSONObject = JSON.parse(jsonCons);
+		function getResults(jsonCons,facetName,facetValue,operation){
+			//clears the content of div because it'll be filled by explorer posts
+			//$("#tempEntityHubSuggestions").empty();
+			$("#allSuggestions").remove();
+						
+			var keywordToSearch = $("#keywordIn").val();
 			
-			if(JSONObject[facetName] != null)
+			if(typeof(jsonCons) == "undefined") {
+				jsonCons = "{}";
+				var suggestedList = JSON.parse('{"keywords" : []}');
+				suggestedList['keywords'].push($("#keywordIn").val());
+				$("#suggestedKeywordList").text(JSON.stringify(suggestedList));
+			}
+			var JSONObject = JSON.parse(jsonCons);
+			if(typeof(facetName) != "undefined" || typeof(facetValue != "undefined")) {
+							
+				if(operation == "addFacet") {
+	
+					
+					if(JSONObject[facetName] != null)
+					{
+						if(JSONObject[facetName].indexOf(facetValue) == -1) {
+							JSONObject[facetName].push(facetValue);
+						}
+					} else {
+						JSONObject[facetName] = new Array();
+						JSONObject[facetName].push(facetValue);
+					}
+				}
+				
+				else if(operation == "deleteFacet") {
+					var  values = JSONObject[facetName];
+					
+					var length=0;
+					var index;
+					for(var value in values) {			
+						if(typeof(JSONObject[facetName][value]) != "undefined") {
+							length++;
+							if(JSONObject[facetName][value] == facetValue) {
+								index = value;
+							}
+						}
+					}			
+					
+					if(length == 1) {
+						delete JSONObject[facetName];
+					} else {
+						<#-- TODO: change -->
+						delete JSONObject[facetName][index];
+					}
+				}
+				
+			}
+			if(operation == "explore")
 			{
-				if(JSONObject[facetName].indexOf(facetValue) == -1) {
-					JSONObject[facetName].push(facetValue);
+				
+				$("#keywordIn").val(facetValue);
+				var suggestedList = JSON.parse(document.getElementById("suggestedKeywordList").innerHTML);
+				
+				var previousString = "";
+				for(i = 0; i  < suggestedList['keywords'].length ; i++)
+				{
+					if(i != 0)
+					{
+						previousString += " > ";
+					}
+					previousString += "<a href=javascript:getResults(null,null,'" + suggestedList['keywords'][i] + "','previousSuggestion')> " + suggestedList['keywords'][i] + "</a>";
 				}
-			} else {
+				$("#previousSuggestionButton").html(previousString);
+				//adds the last entered word to list and saves it in a hidden division
+				suggestedList['keywords'].push(facetValue);
+				
+				//decides when to show back division
+				if(suggestedList['keywords'].length > 1)
+				{
+					$("#previousSuggestionButton").removeClass('invisible');
+				}
+				else
+				{
+					$("#previousSuggestionButton").addClass('invisible');
+				}
+				$("#suggestedKeywordList").text(JSON.stringify(suggestedList));
+			}
+			
+			//if back button is pressed, previous suggestion is searched again and suggestionList is fixed
+			else if(operation == "previousSuggestion")
+			{
+				var suggestedList = (JSON.parse(document.getElementById("suggestedKeywordList").innerHTML));
+				var length = suggestedList['keywords'].length;
+				var index = suggestedList['keywords'].indexOf(facetValue);
+				
+				suggestedList['keywords'] = suggestedList['keywords'].slice(0,index);				
+				
+				$("#suggestedKeywordList").text(JSON.stringify(suggestedList));
+				getResults(null,null,facetValue,"explore");
+			}
+			else if(operation == "date"){
+			
+				var JSONObject = JSON.parse(jsonCons);
+				var facetValue = "[" + document.getElementById("dateFrom").value + "T00:00:00Z TO " + 
+										document.getElementById("dateTo").value + "T23:59:59Z]";
 				JSONObject[facetName] = new Array();
 				JSONObject[facetName].push(facetValue);
 			}
-		
+			else if(operation == "range"){
+			
+				var JSONObject = JSON.parse(jsonCons);
+				var facetValue = "[" + document.getElementById(facetName+"TextMin").value + " TO " + 
+										document.getElementById(facetName+"TextMax").value + "]";
+										
+				JSONObject[facetName] = new Array();
+				JSONObject[facetName].push(facetValue);
+			}
+			
 			//accumulate all selected engines in an array
 			var engines_selected = [];
 			$(".searchengine ").each(function(){
@@ -158,9 +214,49 @@
 					engines_selected.push($(this).val());
 				}	
 			});
-		     
-			var graph_selected = $("#graphIn option:selected").val();
-	
+		    
+		    //make text area invisible
+			//	$("#searchResult").fadeOut(100);
+			//	$("#resultContainer").fadeOut(100);
+				//show busy icon
+				$("#busyIcon").removeClass("invisible");
+		    
+			var graph_selected = "";
+			var graphInCombo = document.getElementById('graphIn');
+			if (graphInCombo != null) {
+				var selectedIndex = graphInCombo.selectedIndex;
+				if(selectedIndex != 0) {
+					graph_selected = $("#graphIn option:selected").val();
+				}
+			}
+			//means if there is need to recalculate the suggestions from mexternal resource such as entityhub
+			if(operation == "first" || operation == "explore" || operation == "previousSuggestion") {
+				$.ajax({
+					url : "${it.publicBaseUri}contenthub/search/suggestion",
+					type : "POST",
+					async: true,
+					data: {keyword: $("#keywordIn").val()},
+					dataType: "html",
+					cache: false,
+					success: function(result) {
+						if(!document.getElementById("allSuggestions")) {
+							$("#tempEntityHubSuggestions").text(result);
+						}
+						else {
+						// in this part, gets the result, and checks if it is empty, then dont remove the No Related Keyword Text
+							$("#tempEntityHubSuggestions").text(result);
+							$("#entityHubSuggestionSubDiv").html(result);
+							var x = document.getElementById("entityHubSuggestions").innerHTML;
+							if(x != "\n")
+							$("#noRelatedKeywordDivision").remove();
+						}		
+					},
+					error: function(result) {
+						$("#busyIcon").addClass("invisible");
+						alert(result.status + ' ' + result.statusText);
+					}
+				});
+			}
 			$.ajax({
 				type : "POST",
 				async: true,
@@ -168,7 +264,10 @@
 				dataType: "html",
 				cache: false,
 				success: function(result) {
-					$("#resultContainer > div").replaceWith(result.substr(result.indexOf("</div>")));
+					$("#busyIcon").addClass("invisible");
+					$("#search").addClass("invisible");
+						
+					$("#resultContainer > div:nth-child(2)").replaceWith(result.substr(result.indexOf("</div>")));
 					$(".keywords").accordion({collapsible: true, autoHeight: false });
 					$(".keywords").removeClass("ui-widget");
 					$(".resources > div").tabs({fx: { height: 'toggle', opacity: 'toggle' } });
@@ -180,19 +279,25 @@
 						$(this).next(".collapseContent").slideToggle(500);
 					}); 
 					
-	   				setChosenFacet(JSONObject);
+					setChosenFacet(JSONObject);
+					
+					$("#entityHubSuggestionSubDiv").html($("#tempEntityHubSuggestions").text());
 				},
 				error: function(result) {
 					$("#busyIcon").addClass("invisible");
 					alert(result.status + ' ' + result.statusText);
 				}
 			});
+			
+			
+			
+			
 		}
 	
 		function setChosenFacet(JSONObject)	{
 			var resultString = "";
-			var chosenCons = document.getElementById('chosenFacetsHidden').innerHTML;
-				
+			var chosenCons = $("#chosenFacetsHidden").attr("innerHTML");
+							
 			if(JSONObject != null) {
 				for(var p in JSONObject) {
 					if(JSONObject.hasOwnProperty(p)) {
@@ -200,12 +305,15 @@
 							if(p.hasOwnProperty(value) && typeof(JSONObject[p][value]) != "undefined") {
 								var escapedFacetName = encodeURI(p.toString());
 								var escapedFacetValue = encodeURI(JSONObject[p][value]);
-								var lastindex = p.toString().lastIndexOf("_");
-								var href = "<a href=javascript:deleteCons("; 
+								var startindex = (isReserved(p)) ? p.toString().indexOf("_")+1 : 0;
+								var lastindex = (isReserved(p)) ? p.length : p.toString().lastIndexOf("_");
+								var href = "<a href=javascript:getResults("; 
 								href += 	encodeURI(chosenCons) + ",\"";
-								href +=		escapedFacetName + "\",\"" + escapedFacetValue + "\") title='Remove'>";
+								href +=		escapedFacetName + "\",\"" + escapedFacetValue + "\",\"deleteFacet\") title='Remove'>";
 								href +=     "<img src='${it.staticRootUrl}/contenthub/images/delete_icon_16.png'></a>";
-								href +=		p.toString().substring(0, lastindex) + " : " + JSONObject[p][value] + "<br/>";
+								href +=		p.toString().substring(startindex, lastindex) + " : " + 
+											((isReserved(p)) ? JSONObject[p][value].substring(1,11)+" to "+JSONObject[p][value].substring(25,35) : 
+											JSONObject[p][value]) + "<br/>";
 								resultString += href;
 							}
 						}
@@ -213,73 +321,15 @@
 				}
 			}
 			var a = document.getElementById('chosenFacets');
-			a.outerHTML = resultString;
-			a.innerHTML = resultString;
-		}
-	
-		function deleteCons(jsonCons,facetName,facetValue) {
-
-			var JSONObject = JSON.parse(jsonCons);
-			var  values = JSONObject[facetName];
-			
-			var length=0;
-			var index;
-			for(var value in values) {			
-				if(typeof(JSONObject[facetName][value]) != "undefined") {
-					length++;
-					if(JSONObject[facetName][value] == facetValue) {
-						index = value;
-					}
-				}
+			if(a != null) {
+				a.innerHTML = resultString;
 			}
-			
-			
-			if(length == 1) {
-				delete JSONObject[facetName];
-			} else {
-				<#-- TODO: change -->
-				delete JSONObject[facetName][index];
-			}
-			
-			//accumulate all selected engines in an array
-			var engines_selected = [];
-			$(".searchengine ").each(function(){
-				if($(this).attr("checked")){
-					engines_selected.push($(this).val());
-				}	
-			});
-		     
-			var graph_selected = $("#graphIn option:selected").val();
-	
-			$.ajax({
-				type : "POST",
-				async: true,
-				data: {keywords: $("#keywordIn").val(), graph: graph_selected, engines: engines_selected, constraints: JSON.stringify(JSONObject)},
-				dataType: "html",
-				cache: false,
-				success: function(result) {
-				 
-					$("#resultContainer > div").replaceWith(result.substr(result.indexOf("</div>")));
-					$(".keywords").accordion({collapsible: true, autoHeight: false });
-					$(".keywords").removeClass("ui-widget");
-					$(".resources > div").tabs({fx: { height: 'toggle', opacity: 'toggle' } });
-					$("#resultContainer").fadeIn("slow");
-	       	 
-					//collapsible content
-					$(".collapseItem").click(function(e){
-						e.preventDefault();
-						$(this).next(".collapseContent").slideToggle(500);
-					}); 
-					
-					setChosenFacet(JSONObject);
-				},
-				error: function(result) {
-					$("#busyIcon").addClass("invisible");
-					alert(result.status + ' ' + result.statusText);
-				}
-			});
 		}
-	
+				
+		function isReserved(str){
+			return str.indexOf("stanbolreserved") == 0; 
+		}
+		
 	</script>
 </...@common.page>
-</#escape>
\ No newline at end of file
+</#escape>

Modified: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/result.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/result.ftl?rev=1211477&r1=1211476&r2=1211477&view=diff
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/result.ftl (original)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/result.ftl Wed Dec  7 15:41:42 2011
@@ -16,6 +16,11 @@
 -->
 <#setting url_escaping_charset='ISO-8859-1'>
 <#import "/imports/keyword_result_tab.ftl" as keywordTab>
+<#import "/imports/suggestedKeyword.ftl" as suggestedKeyword>
+<#import "/imports/facetResultMacro.ftl" as facetResultMacro>
+<#import "/imports/relatedKeywordMacro.ftl" as relatedKeywordMacro>
+<#-- limit for the more less button -->
+<#assign limit=4>
 <div id="text">
 </div>
 <div id="result" class="result">
@@ -23,58 +28,50 @@
 	<#assign con=it.templateData.context>
 	<!--General Divs for layout  -->
 	<div class="keywords">
-			<#list con.queryKeyWords?sort_by("scoreString")?reverse as qk>
-
-				<h3  class="keywordItem keywordClickable" id="kw_${qk.keyword?replace("*","_")?replace(" ", "_")?replace("'", "_")}">${qk.scoreString}:${qk.keyword}</h3>
-
+		<#list con.queryKeyWords?sort_by("scoreString")?reverse as qk>
+			<h3  class="keywordItem keywordClickable" id="kw_${qk.keyword?replace("*","_")?replace(" ", "_")?replace("'", "_")}">${qk.keyword}</h3>
+			<div id="allSuggestions">
 				<#if qk.relatedKeywords?exists && qk.relatedKeywords?size != 0>
-				
-					<div>
-						<legend>Related Keywords</legend>
-						<ul class="spadded"> 
-						<#list qk.relatedKeywords?sort_by("scoreString")?reverse as kw>
-							<li class="keywordItem" id="kw_${kw.keyword?replace("*","_")?replace(" ", "_")?replace("'", "_")}"><a class="keywordClickable" href="">${kw.scoreString}:${kw.keyword}</a></li>
-						</#list>
-						<ul>
-					</div>
-						
-				<#else>
-					<div><p><i>No related keywords</i></p></div>
+					<#list qk.relatedKeywords?keys as mapKey>
+						<#assign listOfKey = qk.relatedKeywords[mapKey]>
+						<#if listOfKey?size &gt; 0>
+							<@relatedKeywordMacro.relatedKeywordMacro relatedKeywordList = listOfKey source = mapKey/>
+						</#if>
+					</#list>
 				</#if>
-
-			</#list>
-	
+				<#-- this division includes the results coming from entityHub -->
+				<div id="entityHubSuggestionSubDiv"></div>
+				<#if (!qk.relatedKeywords?exists || qk.relatedKeywords?size == 0) && (!it.suggestions?exists || it.suggestions?size == 0)>
+					<div id="noRelatedKeywordDivision">No related keyword</div>
+				</#if>
+			</div>
+		</#list>
 	</div>
 	
 	<div class="resources">
 		<fieldset>
 			<#list con.queryKeyWords?sort_by("score") as qk>
 				<@keywordTab.keywordTab kw=qk/>
-				<#list qk.relatedKeywords?sort_by("score") as kw1>
-					<@keywordTab.keywordTab kw=kw1/>
-				</#list>
 			</#list>
 		</fieldset>
 	</div>
 	
-	<div id="facets">
+	<div class="chosenfacets">
+		<#if it.templateData.constraints != "{}">
+			<fieldset>
+				<div id="chosenFacets"></div>
+				<div id="chosenFacetsHidden" class="invisible">'${it.templateData.constraints?js_string}'</div>			
+			</fieldset>
+		</#if>
+	</div>
+	<br/>
+	<div class="facets" id="facets">
 
 		<#if it.facets?exists && it.facets?size != 0>
 			<fieldset>
-				<div id="chosenFacets"></div>
-				<div id="chosenFacetsHidden" class="invisible">'${it.templateData.constraints?js_string}'</div>
 				<br/>
 				<#list it.facets as facet>
-					${facet.name?substring(0,facet.name?last_index_of("_"))}
-					<#if facet.values?exists && facet.values?size != 0>
-						<ul>
-							<#list facet.values as value>
-								<#assign consLink = it.templateData.constraints>
-								<li><a href=javascript:getResults('${consLink?url('UTF-8')?js_string}','${facet.name?url('UTF-8')?js_string}','${value.name?url('UTF-8')?js_string}')>${value.name} (${value.count})</a></li>
-								
-							</#list>
-						</ul>
-					</#if>
+					<@facetResultMacro.facetResultMacro facetField=facet consLink=it.templateData.constraints/>
 				</#list>
 			</fieldset>
 		</#if>

Added: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/result_full.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/result_full.ftl?rev=1211477&view=auto
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/result_full.ftl (added)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/result_full.ftl Wed Dec  7 15:41:42 2011
@@ -0,0 +1,384 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<#setting url_escaping_charset='ISO-8859-1'>
+<#escape x as x?html>
+
+<#import "/imports/common.ftl" as common>
+<#import "/imports/keyword_result_tab.ftl" as keywordTab>
+<#import "/imports/suggestedKeyword.ftl" as suggestedKeyword>
+<#import "/imports/facetResultMacro.ftl" as facetResultMacro>
+<#import "/imports/relatedKeywordMacro.ftl" as relatedKeywordMacro>
+
+<#-- limit for the more less button -->
+<#assign limit=4>
+<@common.page title="Search" hasrestapi=false>
+
+	<div id="resultContainer">
+		<input type="hidden" id="keywordIn" value="${it.templateData.keywords}" />
+		<#if it.templateData.engines?exists && it.templateData.engines?size != 0>
+			<#list it.templateData.engines as engine>
+				<input class="searchengine" type="hidden" name="${engine}" value="${engine}" />
+			</#list>
+		</#if>
+		<div id="previousSuggestionButton" class="invisible"></div>
+		<div id="result" class="result">
+			<a href="${it.publicBaseUri}contenthub/search">Back to Search</a></br>
+			<#assign con=it.templateData.context>
+			<!--General Divs for layout  -->
+			
+			<div class="keywords">
+				<#list con.queryKeyWords?sort_by("scoreString")?reverse as qk>
+					<h3  class="keywordItem keywordClickable" id="kw_${qk.keyword?replace("*","_")?replace(" ", "_")?replace("'", "_")}">${qk.keyword}</h3>
+					<div id="allSuggestions">
+						<#if qk.relatedKeywords?exists && qk.relatedKeywords?size != 0>
+							<#list qk.relatedKeywords?keys as mapKey>
+								<#assign listOfKey = qk.relatedKeywords[mapKey]>
+								<#if listOfKey?size &gt; 0>
+									<@relatedKeywordMacro.relatedKeywordMacro relatedKeywordList = listOfKey source = mapKey/>
+								</#if>
+							</#list>
+						</#if>
+						<#-- this division includes the results coming from entityHub -->
+						<div id="entityHubSuggestionSubDiv"></div>
+						<#if (!qk.relatedKeywords?exists || qk.relatedKeywords?size == 0) && (!it.suggestions?exists || it.suggestions?size == 0)>
+							<div id="noRelatedKeywordDivision">No related keyword</div>
+						</#if>
+					</div>
+				</#list>
+			</div>
+			
+			<div class="resources">
+				<fieldset>
+					<#list con.queryKeyWords?sort_by("score") as qk>
+						<@keywordTab.keywordTab kw=qk/>
+					</#list>
+				</fieldset>
+			</div>
+			
+			<div class="chosenfacets">
+				<#if it.templateData.constraints != "{}">
+					<fieldset>
+						<div id="chosenFacets"></div>
+						<div id="chosenFacetsHidden" class="invisible">'${it.templateData.constraints?js_string}'</div>			
+					</fieldset>
+				</#if>
+			</div>
+			<br/>
+			<div class="facets" id="facets">
+		
+				<#if it.facets?exists && it.facets?size != 0>
+					<fieldset>
+						<br/>
+						<#list it.facets as facet>
+							<@facetResultMacro.facetResultMacro facetField=facet consLink=it.templateData.constraints/>
+						</#list>
+					</fieldset>
+				</#if>
+			</div>
+		</div>
+	</div>
+	
+	<!-- To be populated by the second ajax for the suggestions div -->
+	<div id="tempEntityHubSuggestions" class="invisible"></div>
+	
+	<!-- to be populated by the list of suggested keywords to be able to get back in search -->
+	<div id="suggestedKeywordList" class="invisible">{"keywords":[]}</div>	
+	<!-- FIXME put a textarea so jQuery-ui tabs does not expand through footer -->
+	<textarea type="text" disabled="true" style="border-color: #fff; background: white; height:100px; max-height:100px; width:100%; max-width:100%"></textarea>
+	
+	<script language="javascript">
+	
+		$(document).ready(init);
+	
+		function init() {
+		
+			$.ajax({
+				url : "${it.publicBaseUri}contenthub/search/suggestion",
+				type : "POST",
+				async: true,
+				data: {keyword: $("#keywordIn").val()},
+				dataType: "html",
+				cache: false,
+				success: function(result) {
+					if(!document.getElementById("allSuggestions")) {
+						$("#tempEntityHubSuggestions").text(result);
+					}
+					else {
+					// in this part, gets the result, and checks if it is empty, then dont remove the No Related Keyword Text
+						$("#tempEntityHubSuggestions").text(result);
+						$("#entityHubSuggestionSubDiv").html(result);
+						var x = document.getElementById("entityHubSuggestions").innerHTML;
+						if(x != "\n")
+						$("#noRelatedKeywordDivision").remove();
+					}		
+				},
+				error: function(result) {
+					$("#busyIcon").addClass("invisible");
+					alert(result.status + ' ' + result.statusText);
+				}
+			});
+		
+			$(".keywords").accordion({collapsible: true, autoHeight: false });
+			$(".keywords").removeClass("ui-widget");
+			$(".resources > div").tabs({fx: { height: 'toggle', opacity: 'toggle' } });
+			
+			//collapsible content
+			$(".collapseItem").click(function(e){
+				e.preventDefault();
+				$(this).next(".collapseContent").slideToggle(500);
+			}); 
+			
+			$("#entityHubSuggestionSubDiv").html($("#tempEntityHubSuggestions").text());			
+		}
+		
+		function getResults(jsonCons,facetName,facetValue,operation){
+			//clears the content of div because it'll be filled by explorer posts
+			//$("#tempEntityHubSuggestions").empty();
+			$("#allSuggestions").remove();
+						
+			var keywordToSearch = $("#keywordIn").val();
+			
+			if(typeof(jsonCons) == "undefined") {
+				jsonCons = "{}";
+				var suggestedList = JSON.parse('{"keywords" : []}');
+				suggestedList['keywords'].push($("#keywordIn").val());
+				$("#suggestedKeywordList").text(JSON.stringify(suggestedList));
+			}
+			var JSONObject = JSON.parse(jsonCons);
+			if(typeof(facetName) != "undefined" || typeof(facetValue != "undefined")) {
+							
+				if(operation == "addFacet") {
+					if(JSONObject[facetName] != null)
+					{
+						if(JSONObject[facetName].indexOf(facetValue) == -1) {
+							JSONObject[facetName].push(facetValue);
+						}
+					} else {
+						JSONObject[facetName] = new Array();
+						JSONObject[facetName].push(facetValue);
+					}
+				}
+				
+				else if(operation == "deleteFacet") {
+					var  values = JSONObject[facetName];
+					
+					var length=0;
+					var index;
+					for(var value in values) {			
+						if(typeof(JSONObject[facetName][value]) != "undefined") {
+							length++;
+							if(JSONObject[facetName][value] == facetValue) {
+								index = value;
+							}
+						}
+					}			
+					
+					if(length == 1) {
+						delete JSONObject[facetName];
+					} else {
+						<#-- TODO: change -->
+						delete JSONObject[facetName][index];
+					}
+				}
+				
+			}
+			if(operation == "explore")
+			{
+				
+				$("#keywordIn").val(facetValue);
+				var suggestedList = JSON.parse(document.getElementById("suggestedKeywordList").innerHTML);
+				
+				var previousString = "";
+				for(i = 0; i  < suggestedList['keywords'].length ; i++)
+				{
+					if(i != 0)
+					{
+						previousString += " > ";
+					}
+					previousString += "<a href=javascript:getResults(null,null,'" + suggestedList['keywords'][i] + "','previousSuggestion')> " + suggestedList['keywords'][i] + "</a>";
+				}
+				$("#previousSuggestionButton").html(previousString);
+				//adds the last entered word to list and saves it in a hidden division
+				suggestedList['keywords'].push(facetValue);
+				
+				//decides when to show back division
+				if(suggestedList['keywords'].length > 1)
+				{
+					$("#previousSuggestionButton").removeClass('invisible');
+				}
+				else
+				{
+					$("#previousSuggestionButton").addClass('invisible');
+				}
+				$("#suggestedKeywordList").text(JSON.stringify(suggestedList));
+			}
+			
+			//if back button is pressed, previous suggestion is searched again and suggestionList is fixed
+			else if(operation == "previousSuggestion")
+			{
+				var suggestedList = (JSON.parse(document.getElementById("suggestedKeywordList").innerHTML));
+				var length = suggestedList['keywords'].length;
+				var index = suggestedList['keywords'].indexOf(facetValue);
+				
+				suggestedList['keywords'] = suggestedList['keywords'].slice(0,index);				
+				
+				$("#suggestedKeywordList").text(JSON.stringify(suggestedList));
+				getResults(null,null,facetValue,"explore");
+			}
+			else if(operation == "date"){
+			
+				var JSONObject = JSON.parse(jsonCons);
+				var facetValue = "[" + document.getElementById("dateFrom").value + "T00:00:00Z TO " + 
+										document.getElementById("dateTo").value + "T23:59:59Z]";
+				JSONObject[facetName] = new Array();
+				JSONObject[facetName].push(facetValue);
+			}
+			else if(operation == "range"){
+			
+				var JSONObject = JSON.parse(jsonCons);
+				var facetValue = "[" + document.getElementById(facetName+"TextMin").value + " TO " + 
+										document.getElementById(facetName+"TextMax").value + "]";
+										
+				JSONObject[facetName] = new Array();
+				JSONObject[facetName].push(facetValue);
+			}
+			
+			//accumulate all selected engines in an array
+			var engines_selected = [];
+			$(".searchengine").each(function(){
+				engines_selected.push($(this).val());
+			});
+		    
+		    //make text area invisible
+			//	$("#searchResult").fadeOut(100);
+			//	$("#resultContainer").fadeOut(100);
+				//show busy icon
+				$("#busyIcon").removeClass("invisible");
+		    
+			var graph_selected = "";
+			var graphInCombo = document.getElementById('graphIn');
+			if (graphInCombo != null) {
+				var selectedIndex = graphInCombo.selectedIndex;
+				if(selectedIndex != 0) {
+					graph_selected = $("#graphIn option:selected").val();
+				}
+			}
+			//means if there is need to recalculate the suggestions from external resource such as entityhub
+			if(operation == "first" || operation == "explore" || operation == "previousSuggestion") {
+				$.ajax({
+					url : "${it.publicBaseUri}contenthub/search/suggestion",
+					type : "POST",
+					async: true,
+					data: {keyword: $("#keywordIn").val()},
+					dataType: "html",
+					cache: false,
+					success: function(result) {
+						if(!document.getElementById("allSuggestions")) {
+							$("#tempEntityHubSuggestions").text(result);
+						}
+						else {
+						// in this part, gets the result, and checks if it is empty, then dont remove the No Related Keyword Text
+							$("#tempEntityHubSuggestions").text(result);
+							$("#entityHubSuggestionSubDiv").html(result);
+							var x = document.getElementById("entityHubSuggestions").innerHTML;
+							if(x != "\n")
+							$("#noRelatedKeywordDivision").remove();
+						}		
+					},
+					error: function(result) {
+						$("#busyIcon").addClass("invisible");
+						alert(result.status + ' ' + result.statusText);
+					}
+				});
+			}
+			$.ajax({
+				url : "${it.publicBaseUri}contenthub/search",
+				type : "POST",
+				async: true,
+				data: {keywords: $("#keywordIn").val(), graph: graph_selected, engines: engines_selected, constraints: JSON.stringify(JSONObject)},
+				dataType: "html",
+				cache: false,
+				success: function(result) {
+					$("#busyIcon").addClass("invisible");
+					$("#search").addClass("invisible");
+						
+					$("#result").replaceWith(result.substr(result.indexOf("</div>")+6));
+					$(".keywords").accordion({collapsible: true, autoHeight: false });
+					$(".keywords").removeClass("ui-widget");
+					$(".resources > div").tabs({fx: { height: 'toggle', opacity: 'toggle' } });
+					$("#resultContainer").fadeIn("slow");
+	       	 
+					//collapsible content
+					$(".collapseItem").click(function(e){
+						e.preventDefault();
+						$(this).next(".collapseContent").slideToggle(500);
+					}); 
+					
+					setChosenFacet(JSONObject);
+					
+					$("#entityHubSuggestionSubDiv").html($("#tempEntityHubSuggestions").text());
+				},
+				error: function(result) {
+					$("#busyIcon").addClass("invisible");
+					alert(result.status + ' ' + result.statusText);
+				}
+			});
+			
+			
+			
+			
+		}
+	
+		function setChosenFacet(JSONObject)	{
+			var resultString = "";
+			var chosenCons = $("#chosenFacetsHidden").attr("innerHTML");
+							
+			if(JSONObject != null) {
+				for(var p in JSONObject) {
+					if(JSONObject.hasOwnProperty(p)) {
+						for(var value in p) {
+							if(p.hasOwnProperty(value) && typeof(JSONObject[p][value]) != "undefined") {
+								var escapedFacetName = encodeURI(p.toString());
+								var escapedFacetValue = encodeURI(JSONObject[p][value]);
+								var startindex = (isReserved(p)) ? p.toString().indexOf("_")+1 : 0;
+								var lastindex = (isReserved(p)) ? p.length : p.toString().lastIndexOf("_");
+								var href = "<a href=javascript:getResults("; 
+								href += 	encodeURI(chosenCons) + ",\"";
+								href +=		escapedFacetName + "\",\"" + escapedFacetValue + "\",\"deleteFacet\") title='Remove'>";
+								href +=     "<img src='${it.staticRootUrl}/contenthub/images/delete_icon_16.png'></a>";
+								href +=		p.toString().substring(startindex, lastindex) + " : " + 
+											((isReserved(p)) ? JSONObject[p][value].substring(1,11)+" to "+JSONObject[p][value].substring(25,35) : 
+											JSONObject[p][value]) + "<br/>";
+								resultString += href;
+							}
+						}
+					}
+				}
+			}
+			var a = document.getElementById('chosenFacets');
+			if(a != null) {
+				a.innerHTML = resultString;
+			}
+		}
+				
+		function isReserved(str){
+			return str.indexOf("stanbolreserved") == 0; 
+		}
+		
+	</script>
+</...@common.page>
+</#escape>

Added: incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/suggestionResult.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/suggestionResult.ftl?rev=1211477&view=auto
==============================================================================
--- incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/suggestionResult.ftl (added)
+++ incubator/stanbol/trunk/contenthub/web/src/main/resources/org/apache/stanbol/contenthub/web/templates/org/apache/stanbol/contenthub/web/resources/SearchResource/suggestionResult.ftl Wed Dec  7 15:41:42 2011
@@ -0,0 +1,28 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<#setting url_escaping_charset='ISO-8859-1'>
+<#import "/imports/suggestedKeyword.ftl" as suggestedKeyword>
+<div id="entityHubSuggestions">
+	<#if it.suggestions?exists && it.suggestions?size != 0>
+		<#list it.suggestions?keys as mapKey>
+			<#assign setOfKey = it.suggestions[mapKey]>
+			<#if setOfKey?size &gt; 0>
+				<@suggestedKeyword.suggestedKeyword set=setOfKey key=mapKey/>
+			</#if>
+		</#list>
+	</#if>
+</div>
\ No newline at end of file