Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAPI-571 Fix SolrJ Convert Child Docs Correctly #62

Open
wants to merge 1 commit into
base: bw_branch_8_11_2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,66 @@ public SolrInputDocument toSolrInputDocument(Object obj) {
if (field.child != null) {
addChild(obj, field, doc);
} else {
doc.setField(field.name, field.get(obj));
addField(obj, field, doc);
}
}
}
return doc;
}

private void addField(Object obj, DocField field, SolrInputDocument doc) {
Object val = field.get(obj);
if (val != null && isMappedObject(val)) {
if (val instanceof Collection) {
@SuppressWarnings({"rawtypes"})
Collection collection = (Collection) val;
List<SolrInputDocument> docs = new ArrayList<>(collection.size());
for (final Object o : collection) {
final SolrInputDocument inpDoc = toSolrInputDocument(o);
docs.add(inpDoc);
}
val = docs;
} else if (val.getClass().isArray()) {
Object[] objs = (Object[]) val;
SolrInputDocument[] docs = (SolrInputDocument[]) Array.newInstance(SolrInputDocument.class, objs.length);
for (int i = 0; i < objs.length; i++) {
docs[i] = toSolrInputDocument(objs[i]);
}
val = docs;
} else {
val = toSolrInputDocument(val);
}
}

doc.addField(field.name, val);
}

private boolean isMappedObject(Object obj) {
Object first;
if (obj instanceof Collection) {
@SuppressWarnings({"rawtypes"})
Collection collection = (Collection) obj;
if (collection.isEmpty()) {
return false;
}
first = collection.iterator().next();
} else if (obj.getClass().isArray()) {
Object[] objs = (Object[]) obj;
if (objs.length == 0) {
return false;
}
first = objs[0];
} else {
first = obj;
}

return isMappedClass(first.getClass());
}

private boolean isMappedClass(Class clazz) {
return !getDocFields(clazz).isEmpty();
}

private void addChild(Object obj, DocField field, SolrInputDocument doc) {
Object val = field.get(obj);
if (val == null) return;
Expand Down Expand Up @@ -249,6 +302,16 @@ private void storeType() {
if (annotation.child()) {
populateChild(field.getGenericType());
} else {
try {
Class parameterizedType = Class.forName(((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0].getTypeName());
if (isMappedClass(parameterizedType)) {
type = parameterizedType;
return;
}
} catch (ClassNotFoundException e) {
throw new BindingException("Invalid type information available for " + (field == null ? setter : field));
}
type = Object.class;
}
} else if (type == byte[].class) {
Expand Down Expand Up @@ -333,8 +396,18 @@ private void populateChild(Type typ) {
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private Object getFieldValue(SolrDocument solrDocument) {
if (child != null) {
List<SolrDocument> children = solrDocument.getChildDocuments();
if (child != null || isMappedClass(type)) {
List<SolrDocument> children = null;
if(solrDocument.hasChildDocuments()){
children = solrDocument.getChildDocuments();
} else if (solrDocument.getFieldValue(name) != null){
if (isList || isArray) {
children = (List<SolrDocument>) solrDocument.getFieldValue(name);
} else {
children = new ArrayList<>();
children.add((SolrDocument) solrDocument.getFieldValue(name));
}
}
if (children == null || children.isEmpty()) return null;
if (isList) {
ArrayList list = new ArrayList(children.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
import org.junit.Test;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -151,10 +153,94 @@ public void testChild() throws Exception {
assertEquals(arrIn.child[1].name, arrOut.child[1].name);

}
public void testMappedChild() throws Exception {
SingleValueMappedChild in = new SingleValueMappedChild();
in.id = "1";
in.child = new Child();
in.child.id = "1.0";
in.child.name = "Name One";
DocumentObjectBinder binder = new DocumentObjectBinder();
SolrInputDocument solrInputDoc = binder.toSolrInputDocument(in);
SolrDocument solrDoc = toSolrDocument(solrInputDoc);
assertNull(solrInputDoc.getChildDocuments());
assertNull(solrDoc.getChildDocuments());
SingleValueMappedChild out = binder.getBean(SingleValueMappedChild.class, solrDoc);
assertEquals(in.id, out.id);
assertEquals(in.child.id, out.child.id);
assertEquals(in.child.name, out.child.name);

SingleValueMappedChild inNoChild = new SingleValueMappedChild();
in.id = "1-no-child";
SolrInputDocument solrInputDocNoChild = binder.toSolrInputDocument(inNoChild);
SolrDocument solrDocNoChild = toSolrDocument(solrInputDocNoChild);
assertNull(solrInputDocNoChild.getChildDocuments());
assertNull(solrDocNoChild.getChildDocuments());
SingleValueMappedChild outNoChild = binder.getBean(SingleValueMappedChild.class, solrDocNoChild);
assertEquals(inNoChild.id, outNoChild.id);
assertNull(inNoChild.child);
assertNull(outNoChild.child);

ListMappedChild listIn = new ListMappedChild();
listIn.id = "2";
Child child = new Child();
child.id = "1.1";
child.name = "Name Two";
listIn.child = Arrays.asList(in.child, child);
solrInputDoc = binder.toSolrInputDocument(listIn);
solrDoc = toSolrDocument(solrInputDoc);
assertNull(solrInputDoc.getChildDocuments());
assertNull(solrDoc.getChildDocuments());
ListMappedChild listOut = binder.getBean(ListMappedChild.class, solrDoc);
assertEquals(listIn.id, listOut.id);
assertEquals(listIn.child.get(0).id, listOut.child.get(0).id);
assertEquals(listIn.child.get(0).name, listOut.child.get(0).name);
assertEquals(listIn.child.get(1).id, listOut.child.get(1).id);
assertEquals(listIn.child.get(1).name, listOut.child.get(1).name);

ArrayMappedChild arrIn = new ArrayMappedChild();
arrIn.id = "3";
arrIn.child = new Child[]{in.child, child};
solrInputDoc = binder.toSolrInputDocument(arrIn);
solrDoc = toSolrDocument(solrInputDoc);
assertNull(solrInputDoc.getChildDocuments());
assertNull(solrDoc.getChildDocuments());
ArrayMappedChild arrOut = binder.getBean(ArrayMappedChild.class, solrDoc);
assertEquals(arrIn.id, arrOut.id);
assertEquals(arrIn.child[0].id, arrOut.child[0].id);
assertEquals(arrIn.child[0].name, arrOut.child[0].name);
assertEquals(arrIn.child[1].id, arrOut.child[1].id);
assertEquals(arrIn.child[1].name, arrOut.child[1].name);
}

private static SolrDocument toSolrDocument(SolrInputDocument d) {
SolrDocument doc = new SolrDocument();
for (SolrInputField field : d) {
if (field.getValue() != null) {
if (field.getValue() instanceof Collection) {
Collection<?> values = (Collection<?>) field.getValue();
if (!values.isEmpty() && values.iterator().next() instanceof SolrInputDocument) {
List<SolrDocument> docs = new ArrayList<>(values.size());
for (Object value : values) {
docs.add(toSolrDocument((SolrInputDocument) value));
}
doc.setField(field.getName(), docs);
continue;
}
} else if (field.getValue().getClass().isArray()) {
Object[] values = (Object[]) field.getValue();
if (values.length > 0 && values[0] instanceof SolrInputDocument) {
SolrDocument[] docs = new SolrDocument[values.length];
for (int i = 0; i < values.length; i++) {
docs[i] = toSolrDocument((SolrInputDocument) values[i]);
}
doc.setField(field.getName(), docs);
continue;
}
} else if (field.getValue() instanceof SolrInputDocument) {
doc.setField(field.getName(), toSolrDocument((SolrInputDocument) field.getValue()));
continue;
}
}
doc.setField(field.getName(), field.getValue());
}
if (d.getChildDocuments() != null) {
Expand Down Expand Up @@ -245,7 +331,32 @@ public static class ArrayChild {
@Field(child = true)
Child[] child;
}


public static class SingleValueMappedChild {
@Field
String id;

@Field
Child child;
}

public static class ListMappedChild {

@Field
String id;

@Field
List<Child> child;
}

public static class ArrayMappedChild {

@Field
String id;

@Field
Child[] child;
}

public static class NotGettableItem {
@Field
Expand Down
Loading