/**
* 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.
*/
package org.apache.solr.common;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
/**
* A concrete representation of a document within a Solr index. Unlike a lucene
* Document, a SolrDocument may have an Object value matching the type defined in
* schema.xml
*
* For indexing documents, use the SolrInputDocument that contains extra information
* for document and field boosting.
*
* @version $Id: SolrDocument.java 802275 2009-08-08 00:45:15Z yonik $
* @since solr 1.3
*/
public class SolrDocument implements Map<String,Object>, Iterable<Map.Entry<String, Object>>, Serializable
{
private final Map<String,Object> _fields;
public SolrDocument()
{
_fields = new LinkedHashMap<String,Object>();
}
/**
* @return a list of fields defined in this document
*/
public Collection<String> getFieldNames() {
return _fields.keySet();
}
///////////////////////////////////////////////////////////////////
// Add / Set / Remove Fields
///////////////////////////////////////////////////////////////////
/**
* Remove all fields from the document
*/
public void clear()
{
_fields.clear();
}
/**
* Remove all fields with the name
*/
public boolean removeFields(String name)
{
return _fields.remove( name ) != null;
}
/**
* Set a field with the given object. If the object is an Array, it will
* set multiple fields with the included contents. This will replace any existing
* field with the given name
*/
@SuppressWarnings("unchecked")
public void setField(String name, Object value)
{
if( value instanceof Object[] ) {
value = new ArrayList(Arrays.asList( (Object[])value ));
}
else if( value instanceof Collection ) {
// nothing
}
else if( value instanceof Iterable ) {
ArrayList<Object> lst = new ArrayList<Object>();
for( Object o : (Iterable)value ) {
lst.add( o );
}
value = lst;
}
_fields.put(name, value);
}
/**
* This will add a field to the document. If fields already exist with this name
* it will append the collection
*/
@SuppressWarnings("unchecked")
public void addField(String name, Object value)
{
Object existing = _fields.get(name);
if (existing == null) {
this.setField( name, value );
return;
}
Collection<Object> vals = null;
if( existing instanceof Collection ) {
vals = (Collection<Object>)existing;
}
else {
vals = new ArrayList<Object>( 3 );
vals.add( existing );
}
// Add the values to the collection
if( value instanceof Iterable ) {
for( Object o : (Iterable<Object>)value ) {
vals.add( o );
}
}
else if( value instanceof Object[] ) {
for( Object o : (Object[])value ) {
vals.add( o );
}
}
else {
vals.add( value );
}
_fields.put( name, vals );
}
///////////////////////////////////////////////////////////////////
// Get the field values
///////////////////////////////////////////////////////////////////
/**
* returns the first value for a field
*/
public Object getFirstValue(String name) {
Object v = _fields.get( name );
if (v == null || !(v instanceof Collection)) return v;
Collection c = (Collection)v;
if (c.size() > 0 ) {
return c.iterator().next();
}
return null;
}
/**
* Get the value or collection of values for a given field.
*/
public Object getFieldValue(String name) {
return _fields.get( name );
}
/**
* Get a collection of values for a given field name
*/
@SuppressWarnings("unchecked")
public Collection<Object> getFieldValues(String name) {
Object v = _fields.get( name );
if( v instanceof Collection ) {
return (Collection<Object>)v;
}
if( v != null ) {
ArrayList<Object> arr = new ArrayList<Object>(1);
arr.add( v );
return arr;
}
return null;
}
@Override
public String toString()
{
return "SolrDocument["+_fields.toString()+"]";
}
/**
* Iterate of String->Object keys
*/
public Iterator<Entry<String, Object>> iterator() {
return _fields.entrySet().iterator();
}
//-----------------------------------------------------------------------------------------
// JSTL Helpers
//-----------------------------------------------------------------------------------------
/**
* Expose a Map interface to the solr field value collection.
*/
public Map<String,Collection<Object>> getFieldValuesMap()
{
return new Map<String,Collection<Object>>() {
/** Get the field Value */
public Collection<Object> get(Object key) {
return getFieldValues( (String)key );
}
// Easily Supported methods
public boolean containsKey(Object key) { return _fields.containsKey( key ); }
public Set<String> keySet() { return _fields.keySet(); }
public int size() { return _fields.size(); }
public boolean isEmpty() { return _fields.isEmpty(); }
// Unsupported operations. These are not necessary for JSTL
public void clear() { throw new UnsupportedOperationException(); }
public boolean containsValue(Object value) {throw new UnsupportedOperationException();}
public Set<java.util.Map.Entry<String, Collection<Object>>> entrySet() {throw new UnsupportedOperationException();}
public void putAll(Map<? extends String, ? extends Collection<Object>> t) {throw new UnsupportedOperationException();}
public Collection<Collection<Object>> values() {throw new UnsupportedOperationException();}
public Collection<Object> put(String key, Collection<Object> value) {throw new UnsupportedOperationException();}
public Collection<Object> remove(Object key) {throw new UnsupportedOperationException();}
public String toString() {return _fields.toString();}
};
}
/**
* Expose a Map interface to the solr fields. This function is useful for JSTL
*/
public Map<String,Object> getFieldValueMap() {
return new Map<String,Object>() {
/** Get the field Value */
public Object get(Object key) {
return getFirstValue( (String)key );
}
// Easily Supported methods
public boolean containsKey(Object key) { return _fields.containsKey( key ); }
public Set<String> keySet() { return _fields.keySet(); }
public int size() { return _fields.size(); }
public boolean isEmpty() { return _fields.isEmpty(); }
// Unsupported operations. These are not necessary for JSTL
public void clear() { throw new UnsupportedOperationException(); }
public boolean containsValue(Object value) {throw new UnsupportedOperationException();}
public Set<java.util.Map.Entry<String, Object>> entrySet() {throw new UnsupportedOperationException();}
public void putAll(Map<? extends String, ? extends Object> t) {throw new UnsupportedOperationException();}
public Collection<Object> values() {throw new UnsupportedOperationException();}
public Collection<Object> put(String key, Object value) {throw new UnsupportedOperationException();}
public Collection<Object> remove(Object key) {throw new UnsupportedOperationException();}
public String toString() {return _fields.toString();}
};
}
//---------------------------------------------------
// MAP interface
//---------------------------------------------------
public boolean containsKey(Object key) {
return _fields.containsKey(key);
}
public boolean containsValue(Object value) {
return _fields.containsValue(value);
}
public Set<Entry<String, Object>> entrySet() {
return _fields.entrySet();
}
public Object get(Object key) {
return _fields.get(key);
}
public boolean isEmpty() {
return _fields.isEmpty();
}
public Set<String> keySet() {
return _fields.keySet();
}
public Object put(String key, Object value) {
return _fields.put(key, value);
}
public void putAll(Map<? extends String, ? extends Object> t) {
_fields.putAll( t );
}
public Object remove(Object key) {
return _fields.remove(key);
}
public int size() {
return _fields.size();
}
public Collection<Object> values() {
return _fields.values();
}
}