/* * Copyright (c) [2011-2017] "Pivotal Software, Inc." / "Neo Technology" / "Graph Aware Ltd." * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product may include a number of subcomponents with * separate copyright notices and license terms. Your use of the source * code for these subcomponents is subject to the terms and * conditions of the subcomponent's license, as noted in the LICENSE file. * */ /* * Copyright (c) [2011-2017] "Pivotal Software, Inc." / "Neo Technology" / "Graph Aware Ltd." * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product may include a number of subcomponents with * separate copyright notices and license terms. Your use of the source * code for these subcomponents is subject to the terms and * conditions of the subcomponent's license, as noted in the LICENSE file. * */ package org.springframework.data.neo4j.repository.query; import java.util.HashMap; import java.util.Map; import org.neo4j.ogm.metadata.MetaData; import org.neo4j.ogm.model.Result; import org.neo4j.ogm.session.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; /** * Specialisation of {@link RepositoryQuery} that handles mapping to object annotated with <code>@Query</code>. * * @author Mark Angrish * @author Luanne Misquitta * @author Jasper Blues * @author Mark Paluch * @author Nicolas Mervaillie */ public class GraphRepositoryQuery extends AbstractGraphRepositoryQuery { private static final Logger LOG = LoggerFactory.getLogger(GraphRepositoryQuery.class); private final GraphQueryMethod graphQueryMethod; private final Session session; public GraphRepositoryQuery(GraphQueryMethod graphQueryMethod, Session session) { super(graphQueryMethod, session); this.graphQueryMethod = graphQueryMethod; this.session = session; } protected Object doExecute(Query query, Object[] parameters) { if (LOG.isDebugEnabled()) { LOG.debug("Executing query for method {}", graphQueryMethod.getName()); } GraphParameterAccessor accessor = new GraphParametersParameterAccessor(graphQueryMethod, parameters); Class<?> returnType = graphQueryMethod.getMethod().getReturnType(); ResultProcessor processor = graphQueryMethod.getResultProcessor().withDynamicProjection(accessor); Object result = getExecution(accessor).execute(query, processor.getReturnedType().getReturnedType()); return Result.class.equals(returnType) ? result : processor.withDynamicProjection(accessor).processResult(result, new CustomResultConverter(getMetaData(), processor.getReturnedType().getReturnedType())); } // just an horrible trick to get the metadata from OGM private MetaData getMetaData() { return session.doInTransaction((requestHandler, transaction, metaData) -> metaData); } protected Query getQuery(Object[] parameters) { return new Query(getQueryString(), graphQueryMethod.getCountQueryString(), resolveParams(parameters)); } private String getQueryString() { return getQueryMethod().getQuery(); } private Map<String, Object> resolveParams(Object[] parameters) { Map<String, Object> params = new HashMap<>(); Parameters<?, ?> methodParameters = graphQueryMethod.getParameters(); for (int i = 0; i < parameters.length; i++) { Parameter parameter = methodParameters.getParameter(i); Object parameterValue = getParameterValue(parameters[i]); if (parameter.isExplicitlyNamed()) { parameter.getName().ifPresent(name -> params.put(name, parameterValue)); } else { params.put("" + i, parameterValue); } } return params; } private Object getParameterValue(Object parameter) { //The parameter might be an entity, try to resolve its id Object parameterValue = session.resolveGraphIdFor(parameter); if (parameterValue == null) { //Either not an entity or not persisted parameterValue = parameter; } return parameterValue; } @Override protected boolean isCountQuery() { return false; } @Override protected boolean isExistsQuery() { return false; } @Override protected boolean isDeleteQuery() { return false; } }