diff --git a/solr/exampleSolr/conf/schema.xml b/solr/exampleSolr/conf/schema.xml
index 8b70e5ca1..7584c46dd 100644
--- a/solr/exampleSolr/conf/schema.xml
+++ b/solr/exampleSolr/conf/schema.xml
@@ -483,6 +483,8 @@
+
+
@@ -495,6 +497,8 @@
+
+
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/JSONServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/JSONServlet.java
index af6d82d5f..5494938c2 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/JSONServlet.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/JSONServlet.java
@@ -233,7 +233,7 @@ public class JSONServlet extends VitroHttpServlet {
rObj.put("alpha", map.get("alpha"));
List inds = (List)map.get("entities");
- List indsTm = new ArrayList();
+
JSONArray jInds = new JSONArray();
for(Individual ind : inds ){
JSONObject jo = new JSONObject();
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrEntityUrlController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrEntityUrlController.java
new file mode 100644
index 000000000..2cfea4d85
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrEntityUrlController.java
@@ -0,0 +1,162 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+package edu.cornell.mannlib.vitro.webapp.controller;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopDocs;
+
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.rdf.model.ResourceFactory;
+import com.hp.hpl.jena.vocabulary.RDF;
+
+import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc;
+import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc.VitroLuceneTermNames;
+import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneIndexFactory;
+import edu.cornell.mannlib.vitro.webapp.web.ContentType;
+
+
+
+public class SolrEntityUrlController extends VitroHttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ private static final Log log = LogFactory.getLog(SolrEntityUrlController.class.getName());
+ public static final int ENTITY_LIST_CONTROLLER_MAX_RESULTS = 30000;
+
+public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{
+
+ String url = req.getRequestURI().substring(req.getContextPath().length());
+ ContentType contentType = checkForRequestType(req.getHeader("accept"));
+
+ if(Pattern.compile("^/entityurl/$").matcher(url).matches()){
+ String redirectURL = null;
+ if(contentType!=null){
+ if ( RDFXML_MIMETYPE.equals(contentType.getMediaType()))
+ redirectURL = "/entityurl/entityurl.rdf";
+ else if( N3_MIMETYPE.equals(contentType.getMediaType()))
+ redirectURL = "/entityurl/entityurl.n3";
+ else if ( TTL_MIMETYPE.equals(contentType.getMediaType()))
+ redirectURL = "/entityurl/entityurl.ttl";
+ }
+ else{
+ redirectURL = "/entityurl/entityrurl.rdf";
+ }
+
+ String hn = req.getHeader("Host");
+ if (req.isSecure()) {
+ res.setHeader("Location", res.encodeURL("https://" + hn
+ + req.getContextPath() + redirectURL));
+ log.info("doRedirect by using HTTPS");
+ } else {
+ res.setHeader("Location", res.encodeURL("http://" + hn
+ + req.getContextPath() + redirectURL));
+ log.info("doRedirect by using HTTP");
+ }
+ res.setStatus(res.SC_SEE_OTHER);
+ return;
+ }
+
+ String classUri = (String) getServletContext().getAttribute("classuri");
+ BooleanQuery query = new BooleanQuery();
+ query.add(
+ new TermQuery( new Term(VitroLuceneTermNames.RDFTYPE, classUri)),
+ BooleanClause.Occur.MUST );
+
+ IndexSearcher index = LuceneIndexFactory.getIndexSearcher(getServletContext());
+ TopDocs docs = index.search(query, null,
+ ENTITY_LIST_CONTROLLER_MAX_RESULTS,
+ new Sort(VitroLuceneTermNames.NAME_LOWERCASE));
+
+ if( docs == null ){
+ log.error("Search of lucene index returned null");
+ throw new ServletException("Search of lucene index returned null");
+ }
+
+ int ii = 0;
+ int size = docs.totalHits;
+ Resource resource = null;
+ RDFNode node = null;
+ Model model = ModelFactory.createDefaultModel();
+ while( ii < size ){
+ ScoreDoc hit = docs.scoreDocs[ii];
+ if (hit != null) {
+ Document doc = index.doc(hit.doc);
+ if (doc != null) {
+ String uri = doc.getField(VitroLuceneTermNames.URI).stringValue();
+ resource = ResourceFactory.createResource(uri);
+ node = (RDFNode) ResourceFactory.createResource(classUri);
+ model.add(resource, RDF.type, node);
+ } else {
+ log.warn("no document found for lucene doc id " + hit.doc);
+ }
+ } else {
+ log.debug("hit was null");
+ }
+ ii++;
+ }
+
+ String format = "";
+ if(contentType != null){
+ if ( RDFXML_MIMETYPE.equals(contentType.getMediaType()))
+ format = "RDF/XML";
+ else if( N3_MIMETYPE.equals(contentType.getMediaType()))
+ format = "N3";
+ else if ( TTL_MIMETYPE.equals(contentType.getMediaType()))
+ format ="TTL";
+ res.setContentType(contentType.getMediaType());
+ }
+ else{
+ res.setContentType(RDFXML_MIMETYPE);
+ format = "RDF/XML";
+ }
+ model.write(res.getOutputStream(), format);
+}
+public void doPost (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{
+ doGet(req,res);
+}
+
+protected ContentType checkForRequestType(String acceptHeader) {
+ try {
+ //check the accept header
+ if (acceptHeader != null) {
+ List actualContentTypes = new ArrayList();
+ actualContentTypes.add(new ContentType( XHTML_MIMETYPE ));
+ actualContentTypes.add(new ContentType( HTML_MIMETYPE ));
+
+ actualContentTypes.add(new ContentType( RDFXML_MIMETYPE ));
+ actualContentTypes.add(new ContentType( N3_MIMETYPE ));
+ actualContentTypes.add(new ContentType( TTL_MIMETYPE ));
+
+
+ ContentType best = ContentType.getBestContentType(acceptHeader,actualContentTypes);
+ if (best!=null && (
+ RDFXML_MIMETYPE.equals(best.getMediaType()) ||
+ N3_MIMETYPE.equals(best.getMediaType()) ||
+ TTL_MIMETYPE.equals(best.getMediaType()) ))
+ return best;
+ }
+ }
+ catch (Throwable th) {
+ log.error("problem while checking accept header " , th);
+ }
+ return null;
+}
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java
index 0dab98de1..924a6722f 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java
@@ -15,9 +15,7 @@ import javax.servlet.ServletException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.search.ScoreDoc;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
@@ -180,7 +178,7 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
SolrServer solr = SolrSetup.getSolrServer(context);
QueryResponse response = null;
- // Execute lucene query for individuals of the specified type
+ // Execute query for individuals of the specified type
try {
response = solr.query(query);
} catch (Throwable t) {
@@ -197,19 +195,19 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
throw new ServletException("Could not run search in IndividualListController");
}
- // get list of individuals for the search results
- long size = docs.getNumFound();
- log.debug("Number of search results: " + size);
+ // get list of individuals for the search results
+ long size = docs.getNumFound();
+ log.debug("Number of search results: " + size);
- List individuals = new ArrayList((int)size);
- for (SolrDocument doc : docs) {
- String uri = doc.get(VitroLuceneTermNames.URI).toString();
- Individual individual = indDao.getIndividualByURI( uri );
- if (individual != null) {
- individuals.add(individual);
- }
- }
-
+ List individuals = new ArrayList();
+ for (SolrDocument doc : docs) {
+ String uri = doc.get(VitroLuceneTermNames.URI).toString();
+ Individual individual = indDao.getIndividualByURI( uri );
+ if (individual != null) {
+ individuals.add(individual);
+ }
+ }
+
rvMap.put("count", size);
if( size > INDIVIDUALS_PER_PAGE ){
@@ -245,7 +243,8 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
int start = (page-1)*INDIVIDUALS_PER_PAGE;
query.setStart(start)
- .setRows(INDIVIDUALS_PER_PAGE);
+ .setRows(INDIVIDUALS_PER_PAGE)
+ .setSortField("nameLowercaseSingleValued", SolrQuery.ORDER.asc);
log.debug("Query: " + query);
return query;
@@ -314,5 +313,4 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
return selected;
}
}
-
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SolrAutocompleteController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SolrAutocompleteController.java
index 663467256..560ab69cd 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SolrAutocompleteController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SolrAutocompleteController.java
@@ -114,7 +114,6 @@ public class SolrAutocompleteController extends VitroAjaxController {
}
}
- // Since SolrQuery.setSortField() is buggy, sort the results here
Collections.sort(results);
// map.put("results", results);
@@ -157,8 +156,9 @@ public class SolrAutocompleteController extends VitroAjaxController {
}
query.setFields(VitroLuceneTermNames.NAME_RAW, VitroLuceneTermNames.URI); // fields to retrieve
- // Solr bug: generates sort=nameLowercase asc instead of sort=nameLowercase+asc
- //.setSortField(VitroLuceneTermNames.NAME_LOWERCASE, SolrQuery.ORDER.asc);
+
+ // Can't sort on multivalued field, so sort results in Java when we get them
+ // query.setSortField(VitroLuceneTermNames.NAME_LOWERCASE, SolrQuery.ORDER.asc);
return query;
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/Entity2LuceneDoc.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/Entity2LuceneDoc.java
index 30831f197..e4aa2abf5 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/Entity2LuceneDoc.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/Entity2LuceneDoc.java
@@ -80,6 +80,10 @@ public class Entity2LuceneDoc implements Obj2DocIface{
/** rdfs:label lowercased, no tokenizing, no stop words, no stemming **/
public static String NAME_LOWERCASE = "nameLowercase"; // was NAMELOWERCASE
+ /** Same as NAME_LOWERCASE, but single-valued so it's sortable. **/
+ // RY Need to control how indexing selects which of multiple values to copy.
+ public static String NAME_LOWERCASE_SINGLE_VALUED = "nameLowercaseSingleValued";
+
/** rdfs:label lowercased, tokenized, stop words, no stemming.
* Used for autocomplete matching on proper names. **/
public static String AC_NAME_UNSTEMMED = "acNameUnstemmed"; // was NAMEUNSTEMMED