com.yahoo.vespa.DocumentGenMojo Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa;
import com.yahoo.collections.Pair;
import com.yahoo.document.ArrayDataType;
import com.yahoo.document.CollectionDataType;
import com.yahoo.document.DataType;
import com.yahoo.document.Field;
import com.yahoo.document.MapDataType;
import com.yahoo.document.PositionDataType;
import com.yahoo.document.StructDataType;
import com.yahoo.document.StructuredDataType;
import com.yahoo.document.TensorDataType;
import com.yahoo.document.WeightedSetDataType;
import com.yahoo.document.annotation.AnnotationReferenceDataType;
import com.yahoo.document.annotation.AnnotationType;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
import com.yahoo.documentmodel.NewDocumentType;
import com.yahoo.documentmodel.OwnedStructDataType;
import com.yahoo.documentmodel.VespaDocumentType;
import com.yahoo.schema.ApplicationBuilder;
import com.yahoo.schema.Schema;
import com.yahoo.schema.document.FieldSet;
import com.yahoo.schema.parser.ParseException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Generates Vespa document classes from schema files.
*
* @author Vegard Balgaard Havdal
*/
@Mojo(name = "document-gen", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class DocumentGenMojo extends AbstractMojo {
private long newestModifiedTime = 0;
private static final int STD_INDENT = 4;
@Parameter(defaultValue = "${project}", readonly = true)
private MavenProject project;
/**
* Directory containing the schema files
*/
@Parameter(defaultValue = ".", required = true)
private File schemasDirectory;
/**
* Java package for generated classes
*/
@Parameter(defaultValue = "com.yahoo.vespa.document", required = true)
private String packageName;
/**
* User provided annotation types that the plugin should not generate types for. They should however be included in
* ConcreteDocumentFactory.
*/
@Parameter
private List provided = new ArrayList();
/**
* Annotation types for which the generated class should be abstract
*/
@Parameter
private List abztract = new ArrayList();
/**
* Generate source to here.
*/
@Parameter(
property = "plugin.configuration.outputDirectory",
defaultValue="${project.build.directory}/generated-sources/vespa-documentgen-plugin/",
required = true)
private File outputDirectory;
private Map searches;
private Map docTypes;
private Map structTypes;
private Map annotationTypes;
void execute(File schemasDir, File outputDir, String packageName) {
if ("".equals(packageName)) throw new IllegalArgumentException("You may not use empty package for generated types.");
searches = new HashMap<>();
docTypes = new HashMap<>();
structTypes = new HashMap<>();
annotationTypes = new HashMap<>();
outputDir.mkdirs();
ApplicationBuilder builder = buildSearches(schemasDir);
boolean annotationsExported=false;
for (NewDocumentType docType : builder.getModel().getDocumentManager().getTypes()) {
if ( docType != VespaDocumentType.INSTANCE) {
exportDocumentSources(outputDir, docType, packageName);
for (AnnotationType annotationType : docType.getAllAnnotations()) {
if (provided(annotationType.getName())!=null) continue;
annotationsExported=true;
exportAnnotationSources(outputDir, annotationType, docType, packageName);
}
}
}
exportPackageInfo(outputDir, packageName);
if (annotationsExported) exportPackageInfo(outputDir, packageName+".annotation");
exportDocFactory(outputDir, packageName);
if (project!=null) project.addCompileSourceRoot(outputDirectory.toString());
}
private ApplicationBuilder buildSearches(File sdDir) {
File[] sdFiles = sdDir.listFiles((dir, name) -> name.endsWith(".sd"));
ApplicationBuilder builder = new ApplicationBuilder(true);
for (File f : sdFiles) {
try {
long modTime = f.lastModified();
if (modTime > newestModifiedTime) {
newestModifiedTime = modTime;
}
builder.addSchemaFile(f.getAbsolutePath());
} catch (ParseException | IOException e) {
throw new IllegalArgumentException(e);
}
}
builder.build(true);
for (Schema schema : builder.getSchemaList() ) {
this.searches.put(schema.getName(), schema);
}
return builder;
}
/**
* Creates package-info.java, so that the package of the concrete doc types get exported from user's bundle.
*/
private void exportPackageInfo(File outputDir, String packageName) {
File dirForSources = new File(outputDir, packageName.replaceAll("\\.", "/"));
dirForSources.mkdirs();
File target = new File(dirForSources, "package-info.java");
if (target.lastModified() > newestModifiedTime) {
getLog().debug("No changes, not updating "+target);
return;
}
try (Writer out = new FileWriter(target)) {
out.write("@ExportPackage\n" +
"package "+packageName+";\n\n" +
"import com.yahoo.osgi.annotation.ExportPackage;\n");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* The class for this type if provided, otherwise null
*/
private String provided(String annotationType) {
if (provided==null) return null;
for (Annotation a : provided) {
if (a.type.equals(annotationType)) return a.clazz;
}
return null;
}
private boolean isAbstract(String annotationType) {
if (abztract==null) return false;
for (Annotation a : abztract) {
if (a.type.equals(annotationType)) return true;
}
return false;
}
private void exportDocFactory(File outputDir, String packageName) {
File dirForSources = new File(outputDir, packageName.replaceAll("\\.", "/"));
dirForSources.mkdirs();
File target = new File(dirForSources, "ConcreteDocumentFactory.java");
if (target.lastModified() > newestModifiedTime) {
getLog().debug("No changes, not updating "+target);
return;
}
try (Writer out = new FileWriter(target)) {
out.write("package "+packageName+";\n\n" +
"/**\n" +
" * Registry of generated concrete document, struct and annotation types.\n" +
" *\n" +
" * Generated by vespa-documentgen-plugin, do not edit.\n" +
" * Date: "+new Date()+"\n" +
" */\n");
out.write("@com.yahoo.document.Generated\n");
out.write("public class ConcreteDocumentFactory extends com.yahoo.docproc.AbstractConcreteDocumentFactory {\n");
out.write(ind()+"private static java.util.Map> dTypes = new java.util.HashMap>();\n");
out.write(ind()+"private static java.util.Map docTypes = new java.util.HashMap<>();\n");
out.write(ind()+"private static java.util.Map> sTypes = new java.util.HashMap>();\n");
out.write(ind()+"private static java.util.Map> aTypes = new java.util.HashMap>();\n");
out.write(ind()+"static {\n");
for (Map.Entry e : docTypes.entrySet()) {
String docTypeName = e.getKey();
String fullClassName = e.getValue();
out.write(ind(2)+"dTypes.put(\""+docTypeName+"\","+fullClassName+".class);\n");
}
for (Map.Entry e : docTypes.entrySet()) {
String docTypeName = e.getKey();
String fullClassName = e.getValue();
out.write(ind(2)+"docTypes.put(\""+docTypeName+"\","+fullClassName+".type);\n");
}
for (Map.Entry e : structTypes.entrySet()) {
String structTypeName = e.getKey();
String fullClassName = e.getValue();
out.write(ind(2)+"sTypes.put(\""+structTypeName+"\","+fullClassName+".class);\n");
}
for (Map.Entry e : annotationTypes.entrySet()) {
String annotationTypeName = e.getKey();
String fullClassName = e.getValue();
out.write(ind(2)+"aTypes.put(\""+annotationTypeName+"\","+fullClassName+".class);\n");
}
for (Annotation a : provided) {
out.write(ind(2)+"aTypes.put(\""+a.type+"\","+a.clazz+".class);\n");
}
out.write(ind()+"}\n\n");
out.write(
ind()+"public static final java.util.Map> documentTypes = java.util.Collections.unmodifiableMap(dTypes);\n" +
ind()+"public static final java.util.Map documentTypeObjects = java.util.Collections.unmodifiableMap(docTypes);\n" +
ind()+"public static final java.util.Map> structTypes = java.util.Collections.unmodifiableMap(sTypes);\n" +
ind()+"public static final java.util.Map> annotationTypes = java.util.Collections.unmodifiableMap(aTypes);\n\n");
out.write(
ind()+"@Override public java.util.Map> documentTypes() { return ConcreteDocumentFactory.documentTypes; }\n" +
ind()+"@Override public java.util.Map> structTypes() { return ConcreteDocumentFactory.structTypes; }\n" +
ind()+"@Override public java.util.Map> annotationTypes() { return ConcreteDocumentFactory.annotationTypes; }\n\n");
out.write(
ind()+"/**\n" +
ind()+" * Returns a new Document which will be of the correct concrete type and a copy of the given StructFieldValue.\n" +
ind()+" */\n" +
ind()+"@Override public com.yahoo.document.Document getDocumentCopy(java.lang.String type, com.yahoo.document.datatypes.StructuredFieldValue src, com.yahoo.document.DocumentId id) {\n");
for (Map.Entry e : docTypes.entrySet()) {
out.write(ind(2)+"if (\""+e.getKey()+"\".equals(type)) return new "+e.getValue()+"(src, id);\n");
}
out.write(ind(2)+"throw new java.lang.IllegalArgumentException(\"No such concrete document type: \"+type);\n");
out.write(ind()+"}\n\n");
// delete, bad to use reflection?
out.write(
ind()+"/**\n" +
ind()+" * Returns a new Document which will be of the correct concrete type.\n" +
ind()+" */\n" +
ind()+"public static com.yahoo.document.Document getDocument(java.lang.String type, com.yahoo.document.DocumentId id) {\n" +
ind(2)+"if (!ConcreteDocumentFactory.documentTypes.containsKey(type)) throw new java.lang.IllegalArgumentException(\"No such concrete document type: \"+type);\n" +
ind(2)+"try {\n" +
ind(3)+"return ConcreteDocumentFactory.documentTypes.get(type).getConstructor(com.yahoo.document.DocumentId.class).newInstance(id);\n" +
ind(2)+"} catch (java.lang.Exception ex) { throw new java.lang.RuntimeException(ex); }\n" +
ind()+"}\n\n");
// delete, bad to use reflection?
out.write(
ind()+"/**\n" +
ind()+" * Returns a new Struct which will be of the correct concrete type.\n" +
ind()+" */\n" +
ind()+"public static com.yahoo.document.datatypes.Struct getStruct(java.lang.String type) {\n" +
ind(2)+"if (!ConcreteDocumentFactory.structTypes.containsKey(type)) throw new java.lang.IllegalArgumentException(\"No such concrete struct type: \"+type);\n" +
ind(2)+"try {\n" +
ind(3)+"return ConcreteDocumentFactory.structTypes.get(type).getConstructor().newInstance();\n" +
ind(2)+"} catch (java.lang.Exception ex) { throw new java.lang.RuntimeException(ex); }\n" +
ind()+"}\n\n");
// delete, bad to use reflection?
out.write(
ind()+"/**\n" +
ind()+" * Returns a new Annotation which will be of the correct concrete type.\n" +
ind()+" */\n" +
ind()+"public static com.yahoo.document.annotation.Annotation getAnnotation(java.lang.String type) {\n" +
ind(2)+"if (!ConcreteDocumentFactory.annotationTypes.containsKey(type)) throw new java.lang.IllegalArgumentException(\"No such concrete annotation type: \"+type);\n" +
ind(2)+"try {\n" +
ind(3)+"return ConcreteDocumentFactory.annotationTypes.get(type).getConstructor().newInstance();\n" +
ind(2)+"} catch (java.lang.Exception ex) { throw new java.lang.RuntimeException(ex); }\n" +
ind()+"}\n\n");
out.write("}\n");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void exportAnnotationSources(File outputDir, AnnotationType annType, NewDocumentType docType, String packageName) {
File dirForSources = new File(outputDir, packageName.replaceAll("\\.", "/")+"/annotation/");
dirForSources.mkdirs();
String className = className(annType.getName());
File target = new File(dirForSources, className+".java");
if (target.lastModified() > newestModifiedTime) {
getLog().debug("No changes, not updating "+target);
return;
}
try (Writer out = new FileWriter(target)) {
out.write("package "+packageName+".annotation;\n\n" +
"import "+packageName+".ConcreteDocumentFactory;\n" +
exportInnerImportsFromDocAndSuperTypes(docType, packageName) +
exportImportProvidedAnnotationRefs(annType) +
"/**\n" +
" * Generated by vespa-documentgen-plugin, do not edit.\n" +
" * Input annotation type: "+annType.getName()+"\n" +
" * Date: "+new Date()+"\n" +
" */\n" +
"@com.yahoo.document.Generated\n" +
"public "+annTypeModifier(annType)+"class "+className+" extends "+getParentAnnotationType(annType)+" {\n\n");
if (annType.getDataType() instanceof StructDataType) {
out.write(ind() + "public "+className+"() {\n" +
ind(2) + "setType(new com.yahoo.document.annotation.AnnotationType(\""+annType.getName()+"\", Fields.type));\n" +
ind()+"}\n\n");
StructDataType annStruct = (StructDataType)annType.getDataType();
StructDataType annStructTmp = new StructDataType("fields"); // Change the type name
annStructTmp.assign(annStruct);
Collection tmpList = new ArrayList<>();
tmpList.add(annStructTmp);
exportStructTypes(tmpList, out, 1, null);
exportFieldsAndAccessors(className, annStruct.getFieldsThisTypeOnly(), out, 1, false);
out.write(ind()+"@Override public boolean hasFieldValue() { return true; }\n\n");
out.write(ind()+"@Override public com.yahoo.document.datatypes.FieldValue getFieldValue() {\n");
out.write(ind(2)+"com.yahoo.document.datatypes.Struct ret = new Fields();\n");
for (Field f : annStruct.getFields()) {
out.write(
ind(2)+"if ("+getter(f.getName()) +"()!=null) {\n" +
ind(3)+"com.yahoo.document.Field f = ret.getField(\"" + f.getName() + "\");\n" +
ind(3)+"com.yahoo.document.datatypes.FieldValue fv = f.getDataType().createFieldValue(" + getter(f.getName()) + "());\n" +
ind(3)+"ret.setFieldValue(f, fv);\n" +
ind(2)+"}\n");
}
out.write(ind(2)+"return ret;\n");
out.write(ind()+"}\n\n");
} else {
out.write(ind() + "public "+className+"() { setType(new com.yahoo.document.annotation.AnnotationType(\""+annType.getName()+"\")); } \n\n");
out.write(ind()+"@Override public boolean hasFieldValue() { return false; }\n\n");
out.write(ind()+"@Override public com.yahoo.document.datatypes.FieldValue getFieldValue() { return null; }\n\n");
}
out.write("}\n");
annotationTypes.put(annType.getName(), packageName+".annotation."+className);
} catch (IOException e) {
throw new RuntimeException("Could not export sources for annotation type '"+annType.getName()+"'", e);
}
}
/**
* Handle the case of an annotation reference with a type that is user provided, we need to know the class name then
*/
private String exportImportProvidedAnnotationRefs(AnnotationType annType) {
if (annType.getDataType()==null) return "";
StringBuilder ret = new StringBuilder();
for (Field f : ((StructDataType)annType.getDataType()).getFields()) {
if (f.getDataType() instanceof AnnotationReferenceDataType) {
AnnotationReferenceDataType refType = (AnnotationReferenceDataType) f.getDataType();
AnnotationType referenced = refType.getAnnotationType();
String providedClass = provided(referenced.getName());
if (providedClass!=null) {
// Annotationreference is to a type that is user-provided
ret.append("import ").append(providedClass).append(";\n");
}
}
}
return ret.toString();
}
private String annTypeModifier(AnnotationType annType) {
if (isAbstract(annType.getName())) return "abstract ";
return "";
}
private static String exportInnerImportsFromDocAndSuperTypes(NewDocumentType docType, String packageName) {
String ret = "";
ret = ret + "import "+packageName+"."+className(docType.getName())+".*;\n";
ret = ret + exportInnerImportsFromSuperTypes(docType, packageName);
return ret;
}
private static String exportInnerImportsFromSuperTypes(NewDocumentType docType, String packageName) {
StringBuilder ret = new StringBuilder();
for (NewDocumentType inherited : docType.getInherited()) {
if (inherited.getName().equals("document")) continue;
ret.append("import ").append(packageName).append(".").append(className(inherited.getName())).append(".*;\n");
}
return ret.toString();
}
private String getParentAnnotationType(AnnotationType annType) {
if (annType.getInheritedTypes().isEmpty()) return "com.yahoo.document.annotation.Annotation";
String superType = annType.getInheritedTypes().iterator().next().getName();
String providedSuperType = provided(superType);
if (providedSuperType!=null) return providedSuperType;
return className(annType.getInheritedTypes().iterator().next().getName());
}
private void exportDocumentSources(File outputDir, NewDocumentType docType, String packageName) {
File dirForSources = new File(outputDir, packageName.replaceAll("\\.", "/"));
dirForSources.mkdirs();
File target = new File(dirForSources, className(docType.getName())+".java");
if (target.lastModified() > newestModifiedTime) {
getLog().debug("No changes, not updating "+target);
return;
}
try (Writer doc = new FileWriter(target)) {
exportDocumentClass(docType, doc, packageName);
} catch (IOException e) {
throw new RuntimeException("Could not export sources for document type '"+docType.getName()+"'", e);
}
}
/**
* Generates the .java file for the Document subclass for the given document type
*/
private void exportDocumentClass(NewDocumentType docType, Writer out, String packageName) throws IOException {
String className = className(docType.getName());
Pair extendInfo = javaSuperType(docType);
String superType = extendInfo.getFirst();
Boolean multiExtends = extendInfo.getSecond();
out.write(
"package "+packageName+";\n\n" +
exportInnerImportsFromSuperTypes(docType, packageName) +
"/**\n" +
" * Generated by vespa-documentgen-plugin, do not edit.\n" +
" * Input document type: "+docType.getName()+"\n" +
" * Date: "+new Date()+"\n" +
" */\n" +
"@com.yahoo.document.Generated\n" +
"@SuppressWarnings(\"unchecked\")\n" +
"public class "+className+" extends "+superType+" {\n\n"+
ind(1)+"/** The doc type of this.*/\n" +
ind(1)+"public static final com.yahoo.document.DocumentType type = getDocumentType();\n\n");
// Constructor
out.write(
ind(1)+"public "+className+"(com.yahoo.document.DocumentId docId) {\n" +
ind(2)+"super("+className+".type, docId);\n" +
ind(1)+"}\n\n");
out.write(
ind(1)+"protected "+className+"(com.yahoo.document.DocumentType type, com.yahoo.document.DocumentId docId) {\n" +
ind(2)+"super(type, docId);\n" +
ind(1)+"}\n\n");
// isGenerated()
out.write(ind(1)+"@Override protected boolean isGenerated() { return true; }\n\n");
Collection allUniqueFields = getAllUniqueFields(multiExtends, docType.getAllFields());
exportExtendedStructTypeGetter(className, docType.getName(), docType.getInherited(), allUniqueFields, docType.getFieldSets(),
docType.getImportedFieldNames(), out, 1, "getDocumentType", "com.yahoo.document.DocumentType");
exportCopyConstructor(className, out, 1, true);
exportFieldsAndAccessors(className, "com.yahoo.document.Document".equals(superType) ? allUniqueFields : docType.getFields(), out, 1, true);
exportDocumentMethods(allUniqueFields, out, 1);
exportHashCode(allUniqueFields, out, 1, "(getDataType() != null ? getDataType().hashCode() : 0) + getId().hashCode()");
exportEquals(className, allUniqueFields, out, 1);
Set exportedStructs = exportStructTypes(docType.getTypes(), out, 1, null);
if (hasAnyPositionField(allUniqueFields)) {
exportedStructs = exportStructTypes(List.of(PositionDataType.INSTANCE), out, 1, exportedStructs);
}
docTypes.put(docType.getName(), packageName+"."+className);
for (DataType exportedStruct : exportedStructs) {
String fullName = packageName+"."+className+"."+className(exportedStruct.getName());
structTypes.put(exportedStruct.getName(), fullName);
if (exportedStruct instanceof OwnedStructDataType) {
var owned = (OwnedStructDataType) exportedStruct;
structTypes.put(owned.getUniqueName(), fullName);
}
}
out.write("}\n");
}
private static boolean hasAnyPositionDataType(DataType dt) {
if (PositionDataType.INSTANCE.equals(dt)) {
return true;
} else if (dt instanceof CollectionDataType) {
return hasAnyPositionDataType(((CollectionDataType)dt).getNestedType());
} else if (dt instanceof StructuredDataType) {
return hasAnyPositionField(((StructuredDataType)dt).getFields());
} else {
return false;
}
}
private static boolean hasAnyPositionField(Collection fields) {
for (Field f : fields) {
if (hasAnyPositionDataType(f.getDataType())) {
return true;
}
}
return false;
}
private Collection getAllUniqueFields(Boolean multipleInheritance, Collection allFields) {
if (multipleInheritance) {
Map seen = new HashMap<>();
List unique = new ArrayList<>(allFields.size());
for (Field f : allFields) {
if (seen.containsKey(f.getName())) {
if ( ! f.equals(seen.get(f.getName()))) {
throw new IllegalArgumentException("Field '" + f.getName() + "' has conflicting definitions in multiple inheritance." +
"First defined as '" + seen.get(f.getName()) + "', then as '" + f + "'.");
}
} else {
unique.add(f);
seen.put(f.getName(), f);
}
}
return unique;
}
return allFields;
}
/**
* The Java class the class of the given type should inherit from. If the input type inherits from _one_
* other type, use that, otherwise Document.
*/
private static Pair javaSuperType(NewDocumentType docType) {
String ret = "com.yahoo.document.Document";
Collection specInheriteds = specificInheriteds(docType);
boolean singleExtends = singleInheritance(specInheriteds);
if (!specInheriteds.isEmpty() && singleExtends) ret = className(specInheriteds.iterator().next().getName());
return new Pair<>(ret, !singleExtends);
}
private static boolean singleInheritance(Collection specInheriteds) {
if (specInheriteds.isEmpty()) return true;
if (specInheriteds.size()>1) return false;
return singleInheritance(specificInheriteds(specInheriteds.iterator().next()));
}
/**
* The inherited types that are not Document
* @return collection of specific inherited types
*/
private static Collection specificInheriteds(NewDocumentType type) {
List ret = new ArrayList<>();
for (NewDocumentType t : type.getInherited()) {
if (!"document".equals(t.getName())) ret.add(t);
}
return ret;
}
/**
* Exports the copy constructor.
*
* NOTE: This is important, the docproc framework uses that constructor.
*/
private static void exportCopyConstructor(String className, Writer out, int ind, boolean docId) throws IOException {
out.write(
ind(ind)+"/**\n"+
ind(ind)+" * Constructs a "+className+" by taking a deep copy of the provided StructuredFieldValue.\n" +
ind(ind)+" */\n");
if (docId) {
out.write(ind(ind)+"public "+className+"(com.yahoo.document.datatypes.StructuredFieldValue src, com.yahoo.document.DocumentId docId) {\n"+
ind(ind+1)+"super("+className+".type,docId);\n");
} else {
out.write(ind(ind)+"public "+className+"(com.yahoo.document.datatypes.StructuredFieldValue src) {\n"+
ind(ind+1)+"super("+className+".type);\n");
}
out.write(ind(ind+1) + "ConcreteDocumentFactory factory = new ConcreteDocumentFactory();\n");
out.write(
ind(ind+1)+"for (java.util.Iterator>i=src.iterator() ; i.hasNext() ; ) {\n" +
ind(ind+2)+"java.util.Map.Entry e = i.next();\n" +
ind(ind+2)+"com.yahoo.document.Field f = e.getKey();\n" +
ind(ind+2)+"com.yahoo.document.datatypes.FieldValue fv = e.getValue();\n" +
ind(ind+2)+"setFieldValue(f, factory.optionallyUpgrade(f, fv));\n" +
ind(ind+1)+"}\n"+
ind(ind)+"}\n\n");
}
private static void addExtendedField(String className, Field f, Writer out, int ind) throws IOException {
out.write(ind(ind)+ "ret.addField(new com.yahoo.document.ExtendedField(\""+f.getName()+"\", " + toJavaReference(f.getDataType()) + ",\n");
out.write(ind(ind+1) + "new com.yahoo.document.ExtendedField.Extract() {\n");
out.write(ind(ind+2) + "public Object get(com.yahoo.document.datatypes.StructuredFieldValue doc) {return ((" + className + ")doc)." + getter(f.getName()) + "(); }\n");
out.write(ind(ind+2) + "public void set(com.yahoo.document.datatypes.StructuredFieldValue doc, Object value) { ((" + className + ")doc)." + setter(f.getName())+"((" + toJavaType(f.getDataType()) + ")value); }\n");
out.write(ind(ind+1) + "}\n");
out.write(ind(ind) + "));\n");
}
private static void addExtendedStringField(String className, Field f, Writer out, int ind) throws IOException {
out.write(ind(ind)+ "ret.addField(new com.yahoo.document.ExtendedStringField(\""+f.getName()+"\", " + toJavaReference(f.getDataType()) + ",\n");
out.write(ind(ind+1) + "new com.yahoo.document.ExtendedField.Extract() {\n");
out.write(ind(ind+2) + "public Object get(com.yahoo.document.datatypes.StructuredFieldValue doc) {return ((" + className + ")doc)." + getter(f.getName()) + "(); }\n");
out.write(ind(ind+2) + "public void set(com.yahoo.document.datatypes.StructuredFieldValue doc, Object value) { ((" + className + ")doc)." + setter(f.getName())+"((" + toJavaType(f.getDataType()) + ")value); }\n");
out.write(ind(ind+1) + "},\n");
out.write(ind(ind+1) + "new com.yahoo.document.ExtendedStringField.ExtractSpanTrees() {\n");
out.write(ind(ind+2) + "public java.util.Map get(com.yahoo.document.datatypes.StructuredFieldValue doc) {return ((" + className + ")doc)." + spanTreeGetter(f.getName()) + "(); }\n");
out.write(ind(ind+2) + "public void set(com.yahoo.document.datatypes.StructuredFieldValue doc, java.util.Map value) { ((" + className + ")doc)." + spanTreeSetter(f.getName()) + "(value); }\n");
out.write(ind(ind+1) + "}\n");
out.write(ind(ind) + "));\n");
}
private static void exportFieldSetDefinition(Set
© 2015 - 2025 Weber Informatics LLC | Privacy Policy