/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.
*
*/
package org.opencastproject.matterhorn.search.impl;
import static org.opencastproject.matterhorn.search.impl.IndexSchema.FUZZY_FIELDNAME_EXTENSION;
import org.opencastproject.matterhorn.search.Language;
import org.opencastproject.matterhorn.search.SearchMetadata;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
/**
* Document that encapsulates business objects and offers support for adding those objects to a search index.
*/
public final class ElasticsearchDocument extends HashMap<String, Object> {
/** Serial version uid */
private static final long serialVersionUID = 2687550418831284487L;
/** The document identifier */
private String id = null;
/** The document type */
private String type = null;
/**
* Creates a new elastic search document based on the id, the document type and the metadata.
* <p>
* Note that the type needs to map to an Elasticsearch document type mapping.
*
* @param id
* the resource identifier.
* @param type
* the document type
* @param resource
* the resource metadata
*/
public ElasticsearchDocument(String id, String type, List<SearchMetadata<?>> resource) {
this.id = id;
this.type = type;
for (SearchMetadata<?> entry : resource) {
String metadataKey = entry.getName();
put(metadataKey, entry.getValues());
// TODO Not sure what to use for localizedFulltextFieldName
if (entry.addToText())
addToFulltext(entry, IndexSchema.TEXT, IndexSchema.TEXT);
}
}
/**
* Returns the document type.
*
* @return the type
*/
public String getType() {
return type;
}
/**
* Adds the resource metadata to the designated fulltext fields.
*
* @param item
* the metadata item
* @param fulltextFieldName
* the fulltext field name
* @param localizedFulltextFieldName
* the localized fulltext field name
*/
@SuppressWarnings("unchecked")
private void addToFulltext(SearchMetadata<?> item, String fulltextFieldName, String localizedFulltextFieldName) {
// Get existing fulltext entries
Collection<String> fulltext = (Collection<String>) get(fulltextFieldName);
if (fulltext == null) {
fulltext = new ArrayList<String>();
put(fulltextFieldName, fulltext);
put(fulltextFieldName + FUZZY_FIELDNAME_EXTENSION, fulltext);
}
// Language neutral elements
for (Object value : item.getValues()) {
if (value.getClass().isArray()) {
Object[] fieldValues = (Object[]) value;
for (Object v : fieldValues) {
fulltext.add(v.toString());
}
} else {
fulltext.add(value.toString());
}
}
// Add localized metadata values
for (Language language : item.getLocalizedValues().keySet()) {
// Get existing fulltext entries
String localizedFieldName = MessageFormat.format(localizedFulltextFieldName, language.getIdentifier());
Collection<String> localizedFulltext = (Collection<String>) get(localizedFieldName);
if (fulltext == null) {
fulltext = new ArrayList<String>();
put(localizedFieldName, fulltext);
}
Collection<?> values = item.getLocalizedValues().get(language);
for (Object value : values) {
if (value.getClass().isArray()) {
Object[] fieldValues = (Object[]) value;
for (Object v : fieldValues) {
localizedFulltext.add(v.toString());
}
} else {
localizedFulltext.add(value.toString());
}
}
}
}
/**
* Returns the identifier.
*
* @return the identifier
*/
public String getUID() {
return id;
}
}