add AdvancedSolrDocumentConverter

- this advanced converter is able to convert a Record into SolrInputDocument while handle atomic updates
diff --git a/core/org.eclipse.smila.solr/code/src/org/eclipse/smila/solr/update/AdvancedSolrDocumentConverter.java b/core/org.eclipse.smila.solr/code/src/org/eclipse/smila/solr/update/AdvancedSolrDocumentConverter.java
new file mode 100644
index 0000000..96abf89
--- /dev/null
+++ b/core/org.eclipse.smila.solr/code/src/org/eclipse/smila/solr/update/AdvancedSolrDocumentConverter.java
@@ -0,0 +1,103 @@
+/**
+ *
+ */
+package org.eclipse.smila.solr.update;
+
+import java.util.Map.Entry;
+
+import org.apache.solr.common.SolrInputDocument;
+import org.eclipse.smila.datamodel.Any;
+import org.eclipse.smila.datamodel.AnyMap;
+import org.eclipse.smila.datamodel.AnySeq;
+import org.eclipse.smila.datamodel.Record;
+import org.eclipse.smila.datamodel.Value;
+import org.eclipse.smila.datamodel.util.AnyUtil;
+
+import com.google.common.base.Strings;
+
+/**
+ * @author pwissel
+ *
+ */
+public class AdvancedSolrDocumentConverter {
+
+  private final AnyMap _mapping;
+
+  public AdvancedSolrDocumentConverter() {
+    this(null);
+  }
+
+  public AdvancedSolrDocumentConverter(final AnyMap mapping) {
+    _mapping = mapping;
+  }
+
+  public SolrInputDocument convert(final Record record) {
+    if (_mapping != null) {
+      return createDocumentWithMapping(record);
+    }
+    return null;
+  }
+
+  private SolrInputDocument createDocumentWithMapping(final Record record) {
+    final String id = record.getId();
+    final SolrInputDocument document = newDocument(id);
+    for (final Entry<String, Any> mapping : _mapping.entrySet()) {
+      final String attributeOrAttachmentName = mapping.getKey();
+      final Any any = mapping.getValue();
+      final Object fieldName = getFieldName(attributeOrAttachmentName, any);
+      addFieldFromAttribute(document, attributeOrAttachmentName, (String) fieldName, record);
+    }
+    return document;
+  }
+
+  private SolrInputDocument newDocument(final String id) {
+    final SolrInputDocument document = new SolrInputDocument();
+    document.addField(Record.RECORD_ID, id);
+    return document;
+  }
+
+  private Object getFieldName(final String attributeOrAttachmentName, final Any any) {
+    if (any.isValue()) {
+      // AnyValue
+      final Value value = any.asValue();
+      if (value != null) {
+        String fieldName = Strings.emptyToNull(value.asString());
+        return fieldName != null ? fieldName : attributeOrAttachmentName;
+      }
+    } else if (any.isSeq()) {
+      // AnySeq
+      final AnySeq seq = any.asSeq();
+      if (seq != null && !seq.isEmpty()) {
+        return seq.asStrings().toArray(new String[seq.size()]);
+      }
+    } else if (any.isMap()) {
+      final AnyMap map = any.asMap();
+      if (map != null && !map.isEmpty()) {
+        String fieldName = Strings.emptyToNull(map.getStringValue("fieldName"));
+        return fieldName != null ? fieldName : attributeOrAttachmentName;
+      }
+    }
+    return null;
+  }
+
+  private void addFieldFromAttribute(final SolrInputDocument document, final String attributeName,
+    final String fieldName, final Record record) {
+    final Any any = record.getMetadata().get(attributeName);
+    if (any != null) {
+      final Object value = AnyUtil.anyToNative(any);
+      Float boost = null;
+      if (any.isMap()) {
+        final Any boostValue = any.asMap().remove("fieldBoost");
+        if (boostValue != null) {
+          boost = boostValue.asValue().asDouble().floatValue();
+        }
+      }
+      if (boost != null) {
+        document.addField(fieldName, value, boost);
+      } else {
+        document.addField(fieldName, value);
+      }
+    }
+  }
+
+}