package org.gcube.resources.discovery.icclient; import static org.gcube.common.scope.impl.ScopeBean.Type.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.resources.discovery.icclient.stubs.MalformedQueryException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Helper { private static final Logger log = LoggerFactory.getLogger(Helper.class); public static String queryAddAuthenticationControl(String expression) throws MalformedQueryException { String scope = ScopeProvider.instance.get(); if (scope==null || !new ScopeBean(scope).is(VRE)) return expression; int wherePathIndex=0; int returnPathIndex=0; int collIndexEnd=0; int collIndexStart=0; boolean whereFound=false; String forInsertFinal=""; String whereInsertFinal=""; String temp=""; HashMap varReplacementMap = new HashMap(); String forPropertiesString="\n *VAR* in *COLLECTION*/Data \n"; ///child::*[local-name()='Scope'] String forString=" *VAR* in *COLLECTION*/Scopes \n"; String authString=" (functx:is-value-in-sequence('"+scope+"',*VAR*/child::*[local-name()='Scope']/text()) or functx:is-value-in-sequence('"+scope.substring(0,scope.lastIndexOf("/"))+"',*VAR*/child::*[local-name()='Scope']/text())) "; String authStringNormal=" (functx:is-value-in-sequence('"+scope+"',*VAR*/child::*[local-name()='Scope']/text())) "; String queryFiltered; List collInsert= new ArrayList(); Pattern wherePattern= Pattern.compile("where"); //mathcing , $result in $outer/Data Pattern inSubResult= Pattern.compile("(,\\s*([^\\s]*)\\s*in\\s*([^\\s]*)\\s*)(where|order\\sby|return)"); Pattern returnPattern= Pattern.compile("order\\sby|return"); Pattern collectionPattern= Pattern.compile("[^\\s]*\\s*in\\s*collection\\s*[^\\s,]*"); Pattern varPattern= Pattern.compile("[^\\s]*"); Pattern resourcePattern= Pattern.compile("\\scollection\\s*\\([^\\)]*.*/Resource", Pattern.DOTALL); Pattern propertiesPattern=Pattern.compile("\\scollection\\s*\\([^\\)]*.*/Document", Pattern.DOTALL); Matcher varMat; Matcher resourceMat; Matcher collMat=collectionPattern.matcher(expression); collMat.reset(); String forStringTemp=""; while (collMat.find(collIndexEnd)) { try{ collIndexEnd=collMat.end(); temp=collMat.group(); collIndexStart=collMat.start(); }catch(IllegalStateException e){ log.warn("error parsing collection statement"); } varMat= varPattern.matcher(temp); boolean propBool=false; if (temp.contains("/Properties")) { resourceMat= propertiesPattern.matcher(temp); propBool=true; } else resourceMat=resourcePattern.matcher(temp); varMat.lookingAt(); resourceMat.find(); String tempPath=""; try{ tempPath= temp.substring(resourceMat.end()); if (propBool) { String resourceMatString= resourceMat.group(); forStringTemp=forPropertiesString.replace("*VAR*","$entry"+collInsert.size()+"ValueAuth" ).replace("*COLLECTION*", resourceMatString ); String oldVar = varMat.group(); String newVar = "$entry"+collInsert.size()+"ValueAuth"; collInsert.add(true); varReplacementMap.put(oldVar, newVar+"/.."+tempPath); } else { String resourceMatString= resourceMat.group(); String oldVar = varMat.group(); String newVar = "$entry"+collInsert.size()+"ValueAuth"; forStringTemp=forString.replace("*VAR*",newVar ).replace("*COLLECTION*",resourceMatString ); collInsert.add(resourceMatString.contains("/Profiles/RunningInstance") || resourceMatString.contains("/Profiles/GHN") || resourceMatString.contains("/Profiles/Service")); varReplacementMap.put(oldVar, newVar+"/.."+tempPath); } }catch(IllegalStateException e){ log.debug("error parsing statement");} expression=expression.substring(0, collIndexStart)+ forStringTemp +expression.substring(collIndexEnd); collMat=collectionPattern.matcher(expression); } if (collInsert.size()==0) return expression; //concat the let statements for (int i=0; i entry: varReplacementMap.entrySet()) queryFiltered = queryFiltered.replace(entry.getKey(), entry.getValue()); String functionContainsDeclaration =" declare namespace functx = \"http://www.functx.com\"; declare function functx:is-value-in-sequence "+ " ( $value as xs:anyAtomicType? , $seq as xs:anyAtomicType* ) as xs:boolean { $value = $seq } ; \n"; Pattern declarePattern=Pattern.compile("(\\s*declare namespace[^;]*;)*"); Matcher declareMat=declarePattern.matcher(queryFiltered); boolean declareFound = declareMat.find(0); int declareIndex = 0; if (declareFound){ declareIndex = declareMat.end(); queryFiltered = queryFiltered.substring(0, declareIndex)+functionContainsDeclaration+queryFiltered.substring(declareIndex); } else queryFiltered= functionContainsDeclaration +queryFiltered; queryFiltered = queryFiltered.replaceAll("text() ne ","text() != "); log.info("submitting filtered query: {}",queryFiltered); return queryFiltered; } }