/* * Copyright (c) [2011-2016] "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 org.neo4j.ogm.annotation.Property; import org.neo4j.ogm.session.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Method {@link InvocationHandler} used for proxy objects that implement arbitrary interfaces annotated with * <code>@QueryResult</code>. * * @author Adam George */ class QueryResultProxy implements InvocationHandler { private static final Logger log = LoggerFactory.getLogger(QueryResultProxy.class); private static final Pattern beanGetterPattern = Pattern.compile("^(is|get)(\\w+)"); private final Map<String, ?> data; QueryResultProxy(Map<String, ?> queryResults) { this.data = queryResults; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (isNotTraditionalGetter(method)) { log.warn("QueryResult interface method " + method.getName() + " doesn't appear to be a getter and therefore may not return the correct result."); } if (method.isAnnotationPresent(Property.class)) { Property annotation = method.getAnnotation(Property.class); return Utils.coerceTypes(method.getReturnType(), data.get(annotation.name())); } Matcher matcher = beanGetterPattern.matcher(method.getName()); if (matcher.matches()) { String propertyKey = matcher.group(2); propertyKey = propertyKey.substring(0, 1).toLowerCase().concat(propertyKey.substring(1)); return Utils.coerceTypes(method.getReturnType(),data.get(propertyKey)); } return Utils.coerceTypes(method.getReturnType(), data.get(method.getName())); } private boolean isNotTraditionalGetter(Method method) { return method.getParameterTypes().length != 0 || Void.class.equals(method.getReturnType()) || (!method.getName().startsWith("get") && !method.getName().startsWith("is")); } }