/** * Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT * All rights reserved. Use is subject to license terms. See LICENSE.TXT */ package org.diirt.support.cf.formula; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import org.diirt.datasource.formula.StatefulFormulaFunction; import org.diirt.service.ServiceMethod; import org.diirt.service.ServiceRegistry; import org.diirt.vtype.VString; import org.diirt.vtype.VTable; /** * Function that connects to the Channel Finder server, runs the query, * and returns the result. * * @author Kunal Shroff */ public class CFQueryFunction extends StatefulFormulaFunction { // Function state (will be different for each use of the function) private VString currentQuery; private volatile VTable currentResult; private volatile Exception currentException; private ServiceMethod serviceMethod; @Override public boolean isVarArgs() { return false; } @Override public String getName() { return "cfQuery"; } @Override public String getDescription() { return "Query ChannelFinder"; } @Override public List<Class<?>> getArgumentTypes() { return Arrays.<Class<?>>asList(VString.class); } @Override public List<String> getArgumentNames() { return Arrays.asList("query"); } @Override public Class<?> getReturnType() { return VTable.class; } @Override public Object calculate(List<Object> args) { if (currentQuery == null || !((VString) args.get(0)).getValue().equals(currentQuery.getValue())) { currentQuery = (VString) args.get(0); serviceMethod = ServiceRegistry.getDefault().findServiceMethod("cf/find"); serviceMethod.executeAsync(Collections.<String, Object>singletonMap("query", currentQuery), (Map<String, Object> newValue) -> { currentResult = (VTable) newValue.get("result"); currentException = null; }, (Exception newValue) -> { currentException = newValue; currentResult = null; }); } if (currentException != null) { if (currentException instanceof RuntimeException) { throw (RuntimeException) currentException; } else { throw new RuntimeException("Call to ChannelFinder service failed", currentException); } } return currentResult; } }