use of org.opencastproject.search.api.MediaSegmentImpl in project opencast by opencast.
the class SolrRequester method createSearchResult.
/**
* Creates a search result from a given solr response.
*
* @param query
* The solr query.
* @return The search result.
* @throws SolrServerException
* if the solr server is not working as expected
*/
private SearchResult createSearchResult(final SolrQuery query) throws SolrServerException {
// Execute the query and try to get hold of a query response
QueryResponse solrResponse = null;
try {
solrResponse = solrServer.query(query);
} catch (Exception e) {
throw new SolrServerException(e);
}
// Create and configure the query result
final SearchResultImpl result = new SearchResultImpl(query.getQuery());
result.setSearchTime(solrResponse.getQTime());
result.setOffset(solrResponse.getResults().getStart());
result.setLimit(solrResponse.getResults().size());
result.setTotal(solrResponse.getResults().getNumFound());
// Walk through response and create new items with title, creator, etc:
for (final SolrDocument doc : solrResponse.getResults()) {
final SearchResultItemImpl item = SearchResultItemImpl.fill(new SearchResultItem() {
private final String dfltString = null;
@Override
public String getId() {
return Schema.getId(doc);
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.search.api.SearchResultItem#getOrganization()
*/
@Override
public String getOrganization() {
return Schema.getOrganization(doc);
}
@Override
public MediaPackage getMediaPackage() {
MediaPackageBuilder builder = MediaPackageBuilderFactory.newInstance().newMediaPackageBuilder();
if (serializer != null)
builder.setSerializer(serializer);
String mediaPackageFieldValue = Schema.getOcMediapackage(doc);
if (mediaPackageFieldValue != null) {
try {
return builder.loadFromXml(mediaPackageFieldValue);
} catch (Exception e) {
logger.warn("Unable to read media package from search result", e);
}
}
return null;
}
@Override
public long getDcExtent() {
if (getType().equals(SearchResultItemType.AudioVisual)) {
Long extent = Schema.getDcExtent(doc);
if (extent != null)
return extent;
}
return -1;
}
@Override
public String getDcTitle() {
final List<DField<String>> titles = Schema.getDcTitle(doc);
// try to return the first title without any language information first...
return head(filter(titles, new Predicate<DField<String>>() {
@Override
public Boolean apply(DField<String> f) {
return f.getSuffix().equals(Schema.LANGUAGE_UNDEFINED);
}
})).map(new Function<DField<String>, String>() {
@Override
public String apply(DField<String> f) {
return f.getValue();
}
}).getOrElse(new Function0<String>() {
@Override
public String apply() {
// ... since none is present return the first arbitrary title
return Schema.getFirst(titles, dfltString);
}
});
}
@Override
public String getDcSubject() {
return Schema.getFirst(Schema.getDcSubject(doc), dfltString);
}
@Override
public String getDcDescription() {
return Schema.getFirst(Schema.getDcDescription(doc), dfltString);
}
@Override
public String getDcCreator() {
return Schema.getFirst(Schema.getDcCreator(doc), dfltString);
}
@Override
public String getDcPublisher() {
return Schema.getFirst(Schema.getDcPublisher(doc), dfltString);
}
@Override
public String getDcContributor() {
return Schema.getFirst(Schema.getDcContributor(doc), dfltString);
}
@Override
public String getDcAbstract() {
return null;
}
@Override
public Date getDcCreated() {
return Schema.getDcCreated(doc);
}
@Override
public Date getDcAvailableFrom() {
return Schema.getDcAvailableFrom(doc);
}
@Override
public Date getDcAvailableTo() {
return Schema.getDcAvailableTo(doc);
}
@Override
public String getDcLanguage() {
return Schema.getDcLanguage(doc);
}
@Override
public String getDcRightsHolder() {
return Schema.getFirst(Schema.getDcRightsHolder(doc), dfltString);
}
@Override
public String getDcSpatial() {
return Schema.getFirst(Schema.getDcSpatial(doc), dfltString);
}
@Override
public String getDcTemporal() {
return null;
}
@Override
public String getDcIsPartOf() {
return Schema.getDcIsPartOf(doc);
}
@Override
public String getDcReplaces() {
return Schema.getDcReplaces(doc);
}
@Override
public String getDcType() {
return Schema.getDcType(doc);
}
@Override
public String getDcAccessRights() {
return Schema.getFirst(Schema.getDcAccessRights(doc), dfltString);
}
@Override
public String getDcLicense() {
return Schema.getFirst(Schema.getDcLicense(doc), dfltString);
}
@Override
public String getOcMediapackage() {
return Schema.getOcMediapackage(doc);
}
@Override
public SearchResultItemType getType() {
String t = Schema.getOcMediatype(doc);
return t != null ? SearchResultItemType.valueOf(t) : null;
}
@Override
public String[] getKeywords() {
if (getType().equals(SearchResultItemType.AudioVisual)) {
String k = Schema.getOcKeywords(doc);
return k != null ? k.split(" ") : new String[0];
} else
return new String[0];
}
@Override
public String getCover() {
return Schema.getOcCover(doc);
}
@Override
public Date getModified() {
return Schema.getOcModified(doc);
}
@Override
public double getScore() {
return Schema.getScore(doc);
}
@Override
public MediaSegment[] getSegments() {
if (SearchResultItemType.AudioVisual.equals(getType()))
return createSearchResultSegments(doc, query).toArray(new MediaSegmentImpl[0]);
else
return new MediaSegmentImpl[0];
}
});
// Add the item to the result set
result.addItem(item);
}
return result;
}
use of org.opencastproject.search.api.MediaSegmentImpl in project opencast by opencast.
the class SolrRequester method createSearchResultSegments.
/**
* Creates a list of <code>MediaSegment</code>s from the given result document.
*
* @param doc
* the result document
* @param query
* the original query
*/
private List<MediaSegmentImpl> createSearchResultSegments(SolrDocument doc, SolrQuery query) {
List<MediaSegmentImpl> segments = new ArrayList<MediaSegmentImpl>();
// The maximum number of hits in a segment
int maxHits = 0;
// Loop over every segment
for (String fieldName : doc.getFieldNames()) {
if (!fieldName.startsWith(Schema.SEGMENT_TEXT_PREFIX))
continue;
// Ceate a new segment
int segmentId = Integer.parseInt(fieldName.substring(Schema.SEGMENT_TEXT_PREFIX.length()));
MediaSegmentImpl segment = new MediaSegmentImpl(segmentId);
segment.setText(mkString(doc.getFieldValue(fieldName)));
// Read the hints for this segment
Properties segmentHints = new Properties();
try {
String hintFieldName = Schema.SEGMENT_HINT_PREFIX + segment.getIndex();
Object hintFieldValue = doc.getFieldValue(hintFieldName);
segmentHints.load(new ByteArrayInputStream(hintFieldValue.toString().getBytes()));
} catch (IOException e) {
logger.warn("Cannot load hint properties.");
}
// get segment time
String segmentTime = segmentHints.getProperty("time");
if (segmentTime == null)
throw new IllegalStateException("Found segment without time hint");
segment.setTime(Long.parseLong(segmentTime));
// get segment duration
String segmentDuration = segmentHints.getProperty("duration");
if (segmentDuration == null)
throw new IllegalStateException("Found segment without duration hint");
segment.setDuration(Long.parseLong(segmentDuration));
// get preview urls
for (Entry<Object, Object> entry : segmentHints.entrySet()) {
if (entry.getKey().toString().startsWith("preview.")) {
String[] parts = entry.getKey().toString().split("\\.");
segment.addPreview(entry.getValue().toString(), parts[1]);
}
}
// calculate the segment's relevance with respect to the query
String queryText = query.getQuery();
String segmentText = segment.getText();
if (!StringUtils.isBlank(queryText) && !StringUtils.isBlank(segmentText)) {
segmentText = segmentText.toLowerCase();
Pattern p = Pattern.compile(".*fulltext:\\(([^)]*)\\).*");
Matcher m = p.matcher(queryText);
if (m.matches()) {
String[] queryTerms = StringUtils.split(m.group(1).toLowerCase());
int segmentHits = 0;
int textLength = segmentText.length();
for (String t : queryTerms) {
String strippedTerm = StringUtils.strip(t, "*");
if (StringUtils.isBlank(strippedTerm))
continue;
int startIndex = 0;
while (startIndex < textLength - 1) {
int foundAt = segmentText.indexOf(strippedTerm, startIndex);
if (foundAt < 0)
break;
segmentHits++;
startIndex = foundAt + strippedTerm.length();
}
}
// for now, just store the number of hits, but keep track of the maximum hit count
if (segmentHits > 0) {
segment.setHit(true);
segment.setRelevance(segmentHits);
}
if (segmentHits > maxHits)
maxHits = segmentHits;
}
}
segments.add(segment);
}
for (MediaSegmentImpl segment : segments) {
int hitsInSegment = segment.getRelevance();
if (hitsInSegment > 0)
segment.setRelevance((int) ((100 * hitsInSegment) / maxHits));
}
return segments;
}
Aggregations