use of org.opencastproject.search.api.SearchResultItem 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.SearchResultItem in project opencast by opencast.
the class SeriesUpdatedEventHandler method handleEvent.
public void handleEvent(final SeriesItem seriesItem) {
// A series or its ACL has been updated. Find any mediapackages with that series, and update them.
logger.debug("Handling {}", seriesItem);
String seriesId = seriesItem.getSeriesId();
// We must be an administrative user to make this query
final User prevUser = securityService.getUser();
final Organization prevOrg = securityService.getOrganization();
try {
securityService.setUser(SecurityUtil.createSystemUser(systemAccount, prevOrg));
SearchQuery q = new SearchQuery().withSeriesId(seriesId);
SearchResult result = searchService.getForAdministrativeRead(q);
for (SearchResultItem item : result.getItems()) {
MediaPackage mp = item.getMediaPackage();
Organization org = organizationDirectoryService.getOrganization(item.getOrganization());
securityService.setOrganization(org);
// to the distribution channels as well
if (SeriesItem.Type.UpdateAcl.equals(seriesItem.getType())) {
// Build a new XACML file for this mediapackage
Attachment fileRepoCopy = authorizationService.setAcl(mp, AclScope.Series, seriesItem.getAcl()).getB();
// Distribute the updated XACML file
Job distributionJob = distributionService.distribute(CHANNEL_ID, mp, fileRepoCopy.getIdentifier());
JobBarrier barrier = new JobBarrier(null, serviceRegistry, distributionJob);
Result jobResult = barrier.waitForJobs();
if (jobResult.getStatus().get(distributionJob).equals(FINISHED)) {
mp.remove(fileRepoCopy);
mp.add(getFromXml(serviceRegistry.getJob(distributionJob.getId()).getPayload()));
} else {
logger.error("Unable to distribute XACML {}", fileRepoCopy.getIdentifier());
continue;
}
}
// Update the series dublin core
if (SeriesItem.Type.UpdateCatalog.equals(seriesItem.getType())) {
DublinCoreCatalog seriesDublinCore = seriesItem.getMetadata();
mp.setSeriesTitle(seriesDublinCore.getFirst(DublinCore.PROPERTY_TITLE));
// Update the series dublin core
Catalog[] seriesCatalogs = mp.getCatalogs(MediaPackageElements.SERIES);
if (seriesCatalogs.length == 1) {
Catalog c = seriesCatalogs[0];
String filename = FilenameUtils.getName(c.getURI().toString());
URI uri = workspace.put(mp.getIdentifier().toString(), c.getIdentifier(), filename, dublinCoreService.serialize(seriesDublinCore));
c.setURI(uri);
// setting the URI to a new source so the checksum will most like be invalid
c.setChecksum(null);
// Distribute the updated series dc
Job distributionJob = distributionService.distribute(CHANNEL_ID, mp, c.getIdentifier());
JobBarrier barrier = new JobBarrier(null, serviceRegistry, distributionJob);
Result jobResult = barrier.waitForJobs();
if (jobResult.getStatus().get(distributionJob).equals(FINISHED)) {
mp.remove(c);
mp.add(getFromXml(serviceRegistry.getJob(distributionJob.getId()).getPayload()));
} else {
logger.error("Unable to distribute series catalog {}", c.getIdentifier());
continue;
}
}
}
// Remove the series catalog and isPartOf from episode catalog
if (SeriesItem.Type.Delete.equals(seriesItem.getType())) {
mp.setSeries(null);
mp.setSeriesTitle(null);
boolean retractSeriesCatalog = retractSeriesCatalog(mp);
boolean updateEpisodeCatalog = updateEpisodeCatalog(mp);
if (!retractSeriesCatalog || !updateEpisodeCatalog)
continue;
}
// Update the search index with the modified mediapackage
Job searchJob = searchService.add(mp);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, searchJob);
barrier.waitForJobs();
}
} catch (SearchException e) {
logger.warn("Unable to find mediapackages in search: ", e.getMessage());
} catch (UnauthorizedException e) {
logger.warn(e.getMessage());
} catch (MediaPackageException e) {
logger.warn(e.getMessage());
} catch (ServiceRegistryException e) {
logger.warn(e.getMessage());
} catch (NotFoundException e) {
logger.warn(e.getMessage());
} catch (IOException e) {
logger.warn(e.getMessage());
} catch (DistributionException e) {
logger.warn(e.getMessage());
} finally {
securityService.setOrganization(prevOrg);
securityService.setUser(prevUser);
}
}
use of org.opencastproject.search.api.SearchResultItem in project opencast by opencast.
the class SearchServiceImplTest method testAddSimpleMediaPackage.
/**
* Adds a simple media package that has a dublin core for the episode only.
*/
@Test
public void testAddSimpleMediaPackage() throws Exception {
MediaPackage mediaPackage = getMediaPackage("/manifest-simple.xml");
// Make sure our mocked ACL has the read and write permission
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, READ.toString(), true));
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, WRITE.toString(), true));
// Add the media package to the search index
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to add mediapckage did not finish", Job.Status.FINISHED, job.getStatus());
// Make sure it's properly indexed and returned
SearchQuery q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId("10.0000/1");
assertEquals(1, service.getByQuery(q).size());
q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
assertEquals(1, service.getByQuery(q).size());
// Test for various fields
q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId("10.0000/1");
SearchResult result = service.getByQuery(q);
assertEquals(1, result.getTotalSize());
SearchResultItem resultItem = result.getItems()[0];
assertNotNull(resultItem.getMediaPackage());
assertEquals(1, resultItem.getMediaPackage().getCatalogs().length);
}
use of org.opencastproject.search.api.SearchResultItem in project opencast by opencast.
the class AbstractFeedGenerator method createFeed.
/**
* {@inheritDoc}
*/
public final Feed createFeed(Feed.Type type, String[] query, int size, Organization organization) {
logger.debug("Started to create {} feed", type);
SearchResult result = null;
if (type == null)
throw new IllegalArgumentException("Feed type must not be null");
if (size <= 0) {
logger.trace("Using the feed's configured size of {}", this.size);
size = this.size;
}
// Check if the feed generator is correctly set up
if (uri == null)
throw new IllegalStateException("Feed uri (feed.uri) must be configured");
if (name == null)
throw new IllegalStateException("Feed name (feed.name) must be configured");
if (getHome(organization) == null)
throw new IllegalStateException("Feed url (feed.home) must be configured");
if (getLinkTemplate(organization) == null)
throw new IllegalStateException("Feed link template (feed.entry) must be configured");
// Have the concrete implementation load the feed data
result = loadFeedData(type, query, size, DEFAULT_OFFSET);
if (result == null) {
logger.debug("Cannot retrieve solr result for feed '{}' with query '{}'", type.toString(), query);
return null;
}
// Create the feed
Feed f = createFeed(type, getIdentifier(), new ContentImpl(getName()), new ContentImpl(getDescription()), getFeedLink(organization));
f.setEncoding(ENCODING);
// Set iTunes tags
ITunesFeedExtension iTunesFeed = new ITunesFeedExtension();
f.addModule(iTunesFeed);
if (cover != null)
f.setImage(new ImageImpl(cover, "Feed Image"));
// Check if a default format has been specified
// TODO: Parse flavor and set member variable rssTrackFlavor
// String rssFlavor = query.length > 1 ? query[query.length - 1] : null;
// Iterate over the feed data and create the entries
int itemCount = 0;
for (SearchResultItem resultItem : result.getItems()) {
try {
if (resultItem.getType().equals(SearchResultItemType.Series))
addSeries(f, query, resultItem, organization);
else
addEpisode(f, query, resultItem, organization);
} catch (Throwable t) {
logger.error("Error creating entry with id {} for feed {}", resultItem.getId(), this, t);
}
itemCount++;
if (itemCount >= size)
break;
}
return f;
}
Aggregations