Search in sources :

Example 1 with Template

use of ambit2.base.data.Template in project ambit-mirror by ideaconsult.

the class FilteredDatasetResource method createQuery.

@Override
protected Q createQuery(Context context, Request request, Response response) throws ResourceException {
    Template filter = null;
    Form form = getResourceRef(getRequest()).getQueryAsForm();
    try {
        includeMol = "true".equals(form.getFirstValue("mol"));
    } catch (Exception x) {
        includeMol = false;
    }
    Object dataset = form.getFirstValue(OpenTox.params.dataset_uri.toString());
    String[] filteruris = OpenTox.params.filter.getValuesArray(form);
    Object condition = form.getFirstValue(OpenTox.params.condition.toString());
    SetCondition.conditions sc = condition == null ? SetCondition.conditions.in : "no".equals(condition) ? SetCondition.conditions.not_in : SetCondition.conditions.in;
    // if (dataset==null) throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST,"Empty dataset");
    if (filteruris == null)
        throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "No features to filter");
    setTemplate(createTemplate(context, request, response));
    try {
        filter = createTemplate(context, request, response, filteruris);
        if ((filter == null) || (filter.size() == 0))
            throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "No features to filter");
        if (dataset == null) {
            QueryStructureByProperty q = new QueryStructureByProperty();
            q.setFieldname(filter);
            q.setCondition(new SetCondition(sc));
            setPaging(form, q);
            return (Q) q;
        }
        Object q = CallableQueryProcessor.getQueryObject(new Reference(dataset.toString()), getRequest().getRootRef(), getApplication().getContext(), getCookies(), getAgent(), getRequest().getResourceRef().toString());
        if (q == null) {
            throw new ResourceException(Status.SERVER_ERROR_NOT_IMPLEMENTED, "Processing foreign datasets not implemented!");
        } else if (q instanceof QueryDatasetByID) {
            QueryStructureByPropertyInDataset qz = new QueryStructureByPropertyInDataset();
            qz.setValue((QueryDatasetByID) q);
            qz.setFieldname(filter);
            qz.setCondition(new SetCondition(sc));
            setPaging(form, qz);
            return (Q) qz;
        } else if (q instanceof QueryStoredResults) {
            QueryStructuresByPropertyInResults qz = new QueryStructuresByPropertyInResults();
            qz.setValue((QueryStoredResults) q);
            qz.setFieldname(filter);
            qz.setCondition(new SetCondition(sc));
            setPaging(form, qz);
            return (Q) qz;
        } else if (q instanceof QueryStructureByID) {
            QueryStructureByPropertyInCompounds qz = new QueryStructureByPropertyInCompounds();
            qz.setValue((QueryStructureByID) q);
            qz.setFieldname(filter);
            qz.setCondition(new SetCondition(sc));
            setPaging(form, qz);
            return (Q) qz;
        } else
            throw new ResourceException(Status.SERVER_ERROR_NOT_IMPLEMENTED, dataset.toString() + " " + q.getClass().getName() + " not implemented!");
    } catch (ResourceException x) {
        throw x;
    } catch (Exception x) {
        throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, x.getMessage(), x);
    }
}
Also used : Form(org.restlet.data.Form) Reference(org.restlet.data.Reference) QueryStructureByProperty(ambit2.db.search.structure.byproperty.QueryStructureByProperty) SetCondition(net.idea.modbcum.q.conditions.SetCondition) QueryStructureByPropertyInDataset(ambit2.db.search.structure.byproperty.QueryStructureByPropertyInDataset) QueryDatasetByID(ambit2.db.search.structure.QueryDatasetByID) ResourceException(org.restlet.resource.ResourceException) QueryStructureByID(ambit2.db.search.structure.QueryStructureByID) Template(ambit2.base.data.Template) QueryStructureByPropertyInCompounds(ambit2.db.search.structure.byproperty.QueryStructureByPropertyInCompounds) QueryStructuresByPropertyInResults(ambit2.db.search.structure.byproperty.QueryStructuresByPropertyInResults) QueryStoredResults(ambit2.db.search.structure.QueryStoredResults) ResourceException(org.restlet.resource.ResourceException)

Example 2 with Template

use of ambit2.base.data.Template in project ambit-mirror by ideaconsult.

the class StatisticsResource method createQuery.

@Override
protected Q createQuery(Context context, Request request, Response response) throws ResourceException {
    String[] datasetsURI = getParams().getValuesArray(OpenTox.params.dataset_uri.toString());
    Template t = new Template(String.format("%s%s/{%s}", getRequest().getRootRef(), DatasetStructuresResource.dataset, DatasetStructuresResource.datasetKey));
    setStatus(Status.SUCCESS_OK);
    mode = getSearchMode();
    switch(mode) {
        case dataset_intersection:
            {
                QueryCountDatasetIntersection q = null;
                for (int i = 0; i < datasetsURI.length; i++) {
                    if (q == null)
                        q = new QueryCountDatasetIntersection(null);
                    String datasetURI = datasetsURI[i];
                    Map<String, Object> vars = new HashMap<String, Object>();
                    t.parse(datasetURI, vars);
                    if (i == 0)
                        q.setFieldname(vars.get(DatasetStructuresResource.datasetKey).toString());
                    else
                        q.setValue(vars.get(DatasetStructuresResource.datasetKey).toString());
                }
                if (q == null)
                    throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Missing dataset_uri parameters!");
                return (Q) q;
            }
        case structures:
            {
                return (Q) new QueryCount<FACET>(mode.getURL());
            }
        case properties:
            {
                return (Q) new QueryCountProperties(mode.getURL());
            }
        case values:
            {
                return (Q) new QueryCountValues(mode.getURL());
            }
        case dataset:
            {
                return (Q) new QueryCountDataset(mode.getURL());
            }
        case models:
            {
                return (Q) new QueryCountModels(mode.getURL());
            }
        case substances:
            {
                return (Q) new QueryCountSubstances(mode.getURL());
            }
        case substancetypes:
            {
                return (Q) new QueryCountSubstanceTypes(mode.getURL());
            }
        case experiment_endpoints:
            {
                QueryCountEndpoints q = new QueryCountEndpoints(mode.getURL());
                q.setFieldname(getParams().getFirstValue("top"));
                q.setValue(getParams().getFirstValue("category"));
                q.setEndpoint(getParams().getFirstValue("search"));
                return (Q) q;
            }
        case protocol_applications:
            {
                QueryCountProtocolApplications q = new QueryCountProtocolApplications(mode.getURL());
                q.setPageSize(1000);
                // ?bundle_uri=
                // Object bundleURI =
                // OpenTox.params.bundle_uri.getFirstValue(getParams());
                Object bundleURI = getParams().getFirstValue("filterbybundle");
                if (bundleURI != null) {
                    Integer idbundle = getIdBundle(bundleURI, request);
                    q.setBundle(new SubstanceEndpointsBundle(idbundle));
                }
                q.setFieldname(getParams().getFirstValue("topcategory"));
                q.setValue(getParams().getFirstValue("category"));
                return (Q) q;
            }
        case data_availability:
            {
                QueryCountProtocolApplications q = new QueryCountProtocolApplications(mode.getURL(), QueryCountProtocolApplications._mode_related.data_availability);
                q.setPageSize(2000);
                q.setFieldname(getParams().getFirstValue("topcategory"));
                q.setValue(getParams().getFirstValue("category"));
                return (Q) q;
            }
        case study_summary:
            {
                QueryCountProtocolApplications q = new QueryCountProtocolApplications(mode.getURL(), QueryCountProtocolApplications._mode_related.detail);
                q.setPageSize(2000);
                // ?bundle_uri=
                // Object bundleURI =
                // OpenTox.params.bundle_uri.getFirstValue(getParams());
                /*
			 * Object bundleURI = getParams().getFirstValue("filterbybundle");
			 * if (bundleURI!=null) { Integer idbundle = getIdBundle(bundleURI,
			 * request); q.setBundle(new SubstanceEndpointsBundle(idbundle)); }
			 */
                q.setFieldname(getParams().getFirstValue("topcategory"));
                q.setValue(getParams().getFirstValue("category"));
                return (Q) q;
            }
        case interpretation_result:
            {
                QueryCountInterpretationResults q = new QueryCountInterpretationResults(mode.getURL());
                q.setFieldname(getParams().getFirstValue("top"));
                q.setValue(getParams().getFirstValue("category"));
                q.setInterpretation_result(getParams().getFirstValue("search"));
                return (Q) q;
            }
        case chemicals_in_dataset:
            {
                QueryCountChemicalInDataset q = null;
                for (int i = 0; i < datasetsURI.length; i++) {
                    if (q == null)
                        q = new QueryCountChemicalInDataset(mode.getURL());
                    String datasetURI = datasetsURI[i];
                    Map<String, Object> vars = new HashMap<String, Object>();
                    t.parse(datasetURI, vars);
                    q.setFieldname(vars.get(DatasetStructuresResource.datasetKey).toString());
                }
                if (q == null)
                    throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Missing dataset_uri parameters!");
                return (Q) q;
            }
        case bundles:
            {
                return (Q) new QueryCountBundles(mode.getURL());
            }
        default:
            {
                throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
            }
    }
}
Also used : QueryCountDataset(ambit2.db.update.dataset.QueryCountDataset) QueryCountInterpretationResults(ambit2.db.substance.QueryCountInterpretationResults) QueryCountSubstanceTypes(ambit2.db.substance.QueryCountSubstanceTypes) QueryCountDatasetIntersection(ambit2.db.update.dataset.QueryCountDatasetIntersection) QueryCountChemicalInDataset(ambit2.db.update.dataset.QueryCountChemicalInDataset) QueryCountModels(ambit2.db.model.QueryCountModels) QueryCountProtocolApplications(ambit2.db.substance.QueryCountProtocolApplications) Template(org.restlet.routing.Template) QueryCountSubstances(ambit2.db.substance.QueryCountSubstances) SubstanceEndpointsBundle(ambit2.base.data.substance.SubstanceEndpointsBundle) QueryCount(ambit2.db.update.dataset.QueryCount) ResourceException(org.restlet.resource.ResourceException) HashMap(java.util.HashMap) Map(java.util.Map) QueryCountProperties(ambit2.db.update.dataset.QueryCountProperties) QueryCountEndpoints(ambit2.db.substance.QueryCountEndpoints) QueryCountValues(ambit2.db.update.dataset.QueryCountValues) QueryCountBundles(ambit2.db.substance.QueryCountBundles)

Example 3 with Template

use of ambit2.base.data.Template in project ambit-mirror by ideaconsult.

the class AmbitFacetResource method getProperty.

protected Template getProperty(String[] propertyURI, int max) throws ResourceException {
    if (propertyURI == null)
        return null;
    Template profile = new Template();
    Connection connection = null;
    try {
        DBConnection dbc = new DBConnection(getContext());
        connection = dbc.getConnection();
        ProfileReader reader = new ProfileReader(getRequest().getRootRef(), profile, getApplication().getContext(), getToken(), getRequest().getCookies(), getRequest().getClientInfo() == null ? null : getRequest().getClientInfo().getAgent(), getRequest().getResourceRef().toString());
        reader.setCloseConnection(false);
        reader.setConnection(connection);
        for (int i = 0; i < propertyURI.length; i++) {
            reader.process(new Reference(propertyURI[i]));
            if ((i + 1) >= max)
                break;
        }
        return profile;
    } catch (Exception x) {
        throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, x.getMessage(), x);
    } finally {
        try {
            connection.close();
        } catch (Exception x) {
        }
    }
}
Also used : DBConnection(ambit2.rest.DBConnection) ProfileReader(ambit2.rest.property.ProfileReader) Reference(org.restlet.data.Reference) Connection(java.sql.Connection) DBConnection(ambit2.rest.DBConnection) ResourceException(org.restlet.resource.ResourceException) AmbitException(net.idea.modbcum.i.exceptions.AmbitException) ResourceException(org.restlet.resource.ResourceException) Template(ambit2.base.data.Template)

Example 4 with Template

use of ambit2.base.data.Template in project ambit-mirror by ideaconsult.

the class ChartResource method getDataset.

protected ISourceDataset getDataset(String uri) throws InvalidResourceIDException {
    Map<String, Object> vars = new HashMap<String, Object>();
    Template template = OpenTox.URI.dataset.getTemplate(getRequest().getRootRef());
    String id = null;
    try {
        template.parse(uri, vars);
        id = vars.get(OpenTox.URI.dataset.getKey()).toString();
    } catch (Exception x) {
        return null;
    }
    if (id != null)
        try {
            Integer idnum = new Integer(Reference.decode(id.toString()));
            SourceDataset dataset = new SourceDataset();
            dataset.setID(idnum);
            return dataset;
        } catch (NumberFormatException x) {
            if (id.toString().startsWith(DatasetStructuresResource.QR_PREFIX)) {
                String key = id.toString().substring(DatasetStructuresResource.QR_PREFIX.length());
                try {
                    ISourceDataset dataset = new StoredQuery();
                    dataset.setID(Integer.parseInt(key.toString()));
                    return dataset;
                } catch (NumberFormatException xx) {
                    throw new InvalidResourceIDException(id);
                }
            }
        } catch (Exception x) {
            throw new InvalidResourceIDException(id);
        }
    return null;
}
Also used : StoredQuery(ambit2.db.search.StoredQuery) ISourceDataset(ambit2.base.data.ISourceDataset) HashMap(java.util.HashMap) ISourceDataset(ambit2.base.data.ISourceDataset) SourceDataset(ambit2.base.data.SourceDataset) InvalidResourceIDException(ambit2.rest.error.InvalidResourceIDException) ResourceException(org.restlet.resource.ResourceException) IOException(java.io.IOException) InvalidResourceIDException(ambit2.rest.error.InvalidResourceIDException) Template(org.restlet.routing.Template)

Example 5 with Template

use of ambit2.base.data.Template in project ambit-mirror by ideaconsult.

the class StructureQueryResource method createConvertor.

@Override
public RepresentationConvertor createConvertor(Variant variant) throws AmbitException, ResourceException {
    /* workaround for clients not being able to set accept headers */
    if ((queryObject == null) && !(variant.getMediaType().equals(MediaType.TEXT_HTML)))
        throw new NotFoundException();
    setTemplate(template);
    Form acceptform = getResourceRef(getRequest()).getQueryAsForm();
    String media = acceptform.getFirstValue("accept-header");
    if (media != null) {
        variant.setMediaType(new MediaType(media));
    }
    String filenamePrefix = getRequest().getResourceRef().getPath();
    if (variant.getMediaType().equals(ChemicalMediaType.CHEMICAL_MDLSDF)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new SDFReporter<QueryStructureByID>(template, getGroupProperties(), changeLineSeparators), ChemicalMediaType.CHEMICAL_MDLSDF, filenamePrefix);
    } else if (variant.getMediaType().equals(ChemicalMediaType.CHEMICAL_MDLMOL)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new SDFReporter<QueryStructureByID>(new Template(), getGroupProperties(), true, changeLineSeparators), ChemicalMediaType.CHEMICAL_MDLMOL, filenamePrefix);
    } else if (variant.getMediaType().equals(ChemicalMediaType.CHEMICAL_CML)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new CMLReporter<QueryStructureByID>(), ChemicalMediaType.CHEMICAL_CML, filenamePrefix);
    } else if (variant.getMediaType().equals(ChemicalMediaType.CHEMICAL_SMILES)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new SmilesReporter<QueryStructureByID>(true, getTemplate()), ChemicalMediaType.CHEMICAL_SMILES, filenamePrefix);
    } else if (variant.getMediaType().equals(ChemicalMediaType.CHEMICAL_INCHI)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new SmilesReporter<QueryStructureByID>(false, Mode.InChI, getTemplate()), ChemicalMediaType.CHEMICAL_INCHI, filenamePrefix);
    } else if (variant.getMediaType().equals(MediaType.APPLICATION_PDF)) {
        return new PDFConvertor<IStructureRecord, QueryStructureByID, PDFReporter<QueryStructureByID>>(new PDFReporter<QueryStructureByID>(getTemplate(), getGroupProperties()), filenamePrefix);
    } else if (variant.getMediaType().equals(MediaType.TEXT_PLAIN)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(createTXTReporter(), MediaType.TEXT_PLAIN);
    } else if (variant.getMediaType().equals(MediaType.TEXT_URI_LIST)) {
        ConformerURIReporter<QueryStructureByID> reporter = new ConformerURIReporter<QueryStructureByID>(getCompoundInDatasetPrefix(), getRequest(), queryObject.isPrescreen());
        return new StringConvertor(reporter, MediaType.TEXT_URI_LIST, filenamePrefix);
    } else if (variant.getMediaType().equals(MediaType.IMAGE_PNG)) {
        return new ImageConvertor<IStructureRecord, QueryStructureByID>(new ImageReporter<QueryStructureByID>(MediaType.IMAGE_PNG.getMainType(), MediaType.IMAGE_PNG.getSubType()), MediaType.IMAGE_PNG);
    } else if (variant.getMediaType().equals(MediaType.IMAGE_GIF)) {
        return new ImageConvertor<IStructureRecord, QueryStructureByID>(new ImageReporter<QueryStructureByID>(MediaType.IMAGE_GIF.getMainType(), MediaType.IMAGE_GIF.getSubType()), MediaType.IMAGE_GIF);
    } else if (variant.getMediaType().equals(MediaType.APPLICATION_JSON)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new CompoundJSONReporter(getTemplate(), getGroupProperties(), folders, bundles, getRequest(), getRequest().getRootRef().toString() + getCompoundInDatasetPrefix(), includeMol, null), MediaType.APPLICATION_JSON, filenamePrefix);
    } else if (variant.getMediaType().equals(MediaType.APPLICATION_JAVASCRIPT)) {
        String jsonpcallback = getParams().getFirstValue("jsonp");
        if (jsonpcallback == null)
            jsonpcallback = getParams().getFirstValue("callback");
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new CompoundJSONReporter(getTemplate(), getGroupProperties(), folders, bundles, getRequest(), getRequest().getRootRef().toString() + getCompoundInDatasetPrefix(), includeMol, jsonpcallback), MediaType.APPLICATION_JAVASCRIPT, filenamePrefix);
    } else if (variant.getMediaType().equals(ChemicalMediaType.WEKA_ARFF)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new ARFFResourceReporter(getTemplate(), getGroupProperties(), getRequest(), String.format("%s%s", getRequest().getRootRef(), getCompoundInDatasetPrefix())), ChemicalMediaType.WEKA_ARFF, filenamePrefix);
    } else if (variant.getMediaType().equals(ChemicalMediaType.THREECOL_ARFF)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new ARFF3ColResourceReporter(getTemplate(), getGroupProperties(), getRequest(), String.format("%s%s", getRequest().getRootRef(), getCompoundInDatasetPrefix())), ChemicalMediaType.THREECOL_ARFF, filenamePrefix);
    } else if (variant.getMediaType().equals(MediaType.TEXT_CSV)) {
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(createCSVReporter(), MediaType.TEXT_CSV, filenamePrefix);
    } else if (variant.getMediaType().equals(MediaType.APPLICATION_RDF_XML)) {
        switch(rdfwriter) {
            case stax:
                {
                    return new RDFStaXConvertor<IStructureRecord, IQueryRetrieval<IStructureRecord>>(new DatasetRDFStaxReporter(getCompoundInDatasetPrefix(), getRequest(), getTemplate(), getGroupProperties()), filenamePrefix);
                }
            default:
                {
                    // jena
                    return new RDFJenaConvertor<IStructureRecord, IQueryRetrieval<IStructureRecord>>(new DatasetRDFReporter(getCompoundInDatasetPrefix(), getRequest(), variant.getMediaType(), getTemplate(), getGroupProperties()), variant.getMediaType(), filenamePrefix);
                }
        }
    } else if (variant.getMediaType().equals(MediaType.APPLICATION_RDF_TURTLE) || variant.getMediaType().equals(MediaType.TEXT_RDF_N3) || variant.getMediaType().equals(MediaType.TEXT_RDF_NTRIPLES) || variant.getMediaType().equals(MediaType.APPLICATION_RDF_TRIG) || variant.getMediaType().equals(MediaType.APPLICATION_RDF_TRIX) || variant.getMediaType().equals(ChemicalMediaType.APPLICATION_JSONLD)) {
        return new RDFJenaConvertor<IStructureRecord, IQueryRetrieval<IStructureRecord>>(new DatasetRDFReporter(getCompoundInDatasetPrefix(), getRequest(), variant.getMediaType(), getTemplate(), getGroupProperties()), variant.getMediaType(), filenamePrefix);
    } else
        return new OutputWriterConvertor<IStructureRecord, QueryStructureByID>(new SDFReporter<QueryStructureByID>(template, getGroupProperties(), changeLineSeparators), ChemicalMediaType.CHEMICAL_MDLSDF, filenamePrefix);
}
Also used : Form(org.restlet.data.Form) OutputWriterConvertor(net.idea.restnet.db.convertors.OutputWriterConvertor) PDFReporter(ambit2.db.reporters.PDFReporter) NotFoundException(net.idea.modbcum.i.exceptions.NotFoundException) QueryStructureByID(ambit2.db.search.structure.QueryStructureByID) Template(ambit2.base.data.Template) IStructureRecord(ambit2.base.interfaces.IStructureRecord) ARFF3ColResourceReporter(ambit2.rest.dataset.ARFF3ColResourceReporter) SDFReporter(ambit2.db.reporters.SDFReporter) ChemicalMediaType(net.idea.restnet.c.ChemicalMediaType) MediaType(org.restlet.data.MediaType) RDFJenaConvertor(ambit2.rest.RDFJenaConvertor) CompoundJSONReporter(ambit2.rest.structure.CompoundJSONReporter) SmilesReporter(ambit2.db.reporters.SmilesReporter) DatasetRDFStaxReporter(ambit2.rest.dataset.DatasetRDFStaxReporter) StringConvertor(net.idea.restnet.c.StringConvertor) ImageReporter(ambit2.db.reporters.ImageReporter) RDFStaXConvertor(ambit2.rest.RDFStaXConvertor) ARFFResourceReporter(ambit2.rest.dataset.ARFFResourceReporter) ConformerURIReporter(ambit2.rest.structure.ConformerURIReporter) ImageConvertor(ambit2.rest.ImageConvertor) DatasetRDFReporter(ambit2.rest.dataset.DatasetRDFReporter)

Aggregations

Template (ambit2.base.data.Template)35 Property (ambit2.base.data.Property)29 ResourceException (org.restlet.resource.ResourceException)28 AmbitException (net.idea.modbcum.i.exceptions.AmbitException)23 PredictedVarsTemplate (ambit2.base.data.PredictedVarsTemplate)13 ModelQueryResults (ambit2.core.data.model.ModelQueryResults)13 Reference (org.restlet.data.Reference)12 Form (org.restlet.data.Form)11 IStructureRecord (ambit2.base.interfaces.IStructureRecord)10 IOException (java.io.IOException)9 ArrayList (java.util.ArrayList)7 HashMap (java.util.HashMap)7 IDatabaseConnection (org.dbunit.database.IDatabaseConnection)7 ITable (org.dbunit.dataset.ITable)7 Template (org.restlet.routing.Template)7 Dictionary (ambit2.base.data.Dictionary)6 PropertyAnnotation (ambit2.base.data.PropertyAnnotation)6 StoredQuery (ambit2.db.search.StoredQuery)6 LiteratureEntry (ambit2.base.data.LiteratureEntry)5 PropertyAnnotations (ambit2.base.data.PropertyAnnotations)5