2013-01-08 09:15:10 +01:00
package org.gcube.resources.discovery.icclient ;
import static org.gcube.common.scope.impl.ScopeBean.Type.* ;
import java.util.ArrayList ;
2013-01-17 19:03:05 +01:00
import java.util.HashMap ;
2013-01-08 09:15:10 +01:00
import java.util.List ;
2013-01-17 19:03:05 +01:00
import java.util.Map.Entry ;
2013-01-08 09:15:10 +01:00
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 ) ;
2013-01-17 19:03:05 +01:00
2013-01-08 09:15:10 +01:00
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 ;
2016-12-13 14:13:16 +01:00
boolean whereFound = false ;
2013-01-08 09:15:10 +01:00
String forInsertFinal = " " ;
String whereInsertFinal = " " ;
String temp = " " ;
2013-01-17 19:03:05 +01:00
HashMap < String , String > varReplacementMap = new HashMap < String , String > ( ) ;
2013-06-05 15:53:21 +02:00
String forPropertiesString = " \ n *VAR* in *COLLECTION*/Data \ n " ; ///child::*[local-name()='Scope']
2013-01-08 09:15:10 +01:00
String forString = " *VAR* in *COLLECTION*/Scopes \ n " ;
2016-12-13 14:13:16 +01:00
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())) " ;
2017-02-13 11:23:16 +01:00
String authStringNormal = " (functx:is-value-in-sequence(' " + scope + " ',*VAR*/child::*[local-name()='Scope']/text())) " ;
2013-01-08 09:15:10 +01:00
String queryFiltered ;
2013-01-17 19:03:05 +01:00
List < Boolean > collInsert = new ArrayList < Boolean > ( ) ;
2013-01-08 09:15:10 +01:00
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 ( ) ) ;
2013-01-17 19:03:05 +01:00
2013-01-08 09:15:10 +01:00
if ( propBool )
{
String resourceMatString = resourceMat . group ( ) ;
forStringTemp = forPropertiesString . replace ( " *VAR* " , " $entry " + collInsert . size ( ) + " ValueAuth " ) . replace ( " *COLLECTION* " , resourceMatString ) ;
2013-01-17 19:03:05 +01:00
String oldVar = varMat . group ( ) ;
String newVar = " $entry " + collInsert . size ( ) + " ValueAuth " ;
collInsert . add ( true ) ;
2013-06-05 15:53:21 +02:00
2013-01-17 19:03:05 +01:00
varReplacementMap . put ( oldVar , newVar + " /.. " + tempPath ) ;
2013-01-08 09:15:10 +01:00
}
else
{
String resourceMatString = resourceMat . group ( ) ;
2013-01-17 19:03:05 +01:00
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 ) ;
2013-01-08 09:15:10 +01:00
}
} catch ( IllegalStateException e ) { log . debug ( " error parsing statement " ) ; }
2013-01-17 19:03:05 +01:00
expression = expression . substring ( 0 , collIndexStart ) + forStringTemp + expression . substring ( collIndexEnd ) ;
2013-01-08 09:15:10 +01:00
collMat = collectionPattern . matcher ( expression ) ;
}
if ( collInsert . size ( ) = = 0 ) return expression ;
//concat the let statements
for ( int i = 0 ; i < collInsert . size ( ) ; i + + )
if ( i = = collInsert . size ( ) - 1 ) {
2013-01-17 19:03:05 +01:00
if ( collInsert . get ( i ) )
2013-01-08 09:15:10 +01:00
whereInsertFinal + = authString . replace ( " *VAR* " , " $entry " + i + " ValueAuth " ) ;
else whereInsertFinal + = authStringNormal . replace ( " *VAR* " , " $entry " + i + " ValueAuth " ) ;
} else {
2013-01-17 19:03:05 +01:00
if ( collInsert . get ( i ) )
2013-01-08 09:15:10 +01:00
whereInsertFinal + = authString . replace ( " *VAR* " , " $entry " + i + " ValueAuth " ) + " and " ;
else whereInsertFinal + = authStringNormal . replace ( " *VAR* " , " $entry " + i + " ValueAuth " ) + " and " ;
}
Matcher whereMat = wherePattern . matcher ( expression ) ;
Matcher inSubResultMat = inSubResult . matcher ( expression ) ;
Matcher returnMat = returnPattern . matcher ( expression ) ;
whereMat . reset ( ) ;
returnMat . reset ( ) ;
2016-12-13 14:13:16 +01:00
whereFound = whereMat . find ( ) ;
2013-01-08 09:15:10 +01:00
returnMat . find ( ) ;
2013-01-17 19:03:05 +01:00
2013-01-08 09:15:10 +01:00
try {
inSubResultMat . find ( ) ;
} catch ( Exception e ) { }
try {
wherePathIndex = whereMat . start ( ) ;
} catch ( IllegalStateException e ) { log . debug ( " where not found " ) ; }
try {
returnPathIndex = returnMat . start ( ) ;
} catch ( IllegalStateException e ) { log . error ( " error parsing return statement " ) ; throw new MalformedQueryException ( " error parsing return statement " ) ; }
2013-01-17 19:03:05 +01:00
2016-12-13 14:13:16 +01:00
if ( whereFound )
2013-01-08 09:15:10 +01:00
queryFiltered = expression . substring ( 0 , wherePathIndex ) + " \ nwhere " + whereInsertFinal
+ " and ( " + expression . substring ( wherePathIndex + 5 , returnPathIndex ) + " ) \ n " + expression . substring ( returnPathIndex ) ;
else
queryFiltered = expression . substring ( 0 , returnPathIndex ) + " \ nwhere " + whereInsertFinal + " \ n " + expression . substring ( returnPathIndex ) ;
2013-01-17 19:03:05 +01:00
2013-01-08 09:15:10 +01:00
//logger.trace("queryFiltered to match: " + queryFiltered);
Pattern letPattern = Pattern . compile ( " let.*:= " , Pattern . DOTALL ) ;
Matcher letMat = letPattern . matcher ( queryFiltered ) ;
whereMat = wherePattern . matcher ( queryFiltered ) ;
whereMat . reset ( ) ;
whereMat . find ( ) ;
2016-12-13 14:13:16 +01:00
boolean letFound = letMat . find ( collIndexStart ) ;
2013-01-08 09:15:10 +01:00
int letPathIndex = 0 ;
try {
wherePathIndex = whereMat . start ( ) ;
2016-12-13 14:13:16 +01:00
if ( letFound ) letPathIndex = letMat . start ( ) ;
2013-01-08 09:15:10 +01:00
} catch ( IllegalStateException e ) { log . error ( " error parsing let statement " ) ; throw new MalformedQueryException ( " error parsing let statement " ) ; }
2016-12-13 16:01:04 +01:00
2016-12-13 14:13:16 +01:00
if ( ! letFound ) {
2013-01-08 09:15:10 +01:00
queryFiltered = queryFiltered . substring ( 0 , wherePathIndex ) + forInsertFinal + queryFiltered . substring ( wherePathIndex ) ;
}
else {
queryFiltered = queryFiltered . substring ( 0 , letPathIndex ) + forInsertFinal + queryFiltered . substring ( letPathIndex ) ;
}
2013-01-17 19:03:05 +01:00
for ( Entry < String , String > entry : varReplacementMap . entrySet ( ) )
queryFiltered = queryFiltered . replace ( entry . getKey ( ) , entry . getValue ( ) ) ;
2013-01-08 09:15:10 +01:00
2016-12-13 16:01:04 +01:00
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 " ;
2016-12-13 20:03:00 +01:00
Pattern declarePattern = Pattern . compile ( " ( \\ s*declare namespace[^;]*;)* " ) ;
2016-12-13 16:01:04 +01:00
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 ;
2017-02-13 11:23:16 +01:00
queryFiltered = queryFiltered . replaceAll ( " text() ne " , " text() != " ) ;
log . info ( " submitting filtered query: {} " , queryFiltered ) ;
2013-01-08 09:15:10 +01:00
return queryFiltered ;
}
2016-12-13 14:21:59 +01:00
2013-01-08 09:15:10 +01:00
}