You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2012/10/04 14:59:13 UTC

svn commit: r1394034 - in /jena/trunk/jena-arq: Grammar/ src/main/java/com/hp/hpl/jena/sparql/lang/ src/main/java/com/hp/hpl/jena/sparql/lang/arq/ src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/ src/main/java/com/hp/hpl/jena/sparql/sse/builders/ s...

Author: andy
Date: Thu Oct  4 12:59:12 2012
New Revision: 1394034

URL: http://svn.apache.org/viewvc?rev=1394034&view=rev
Log:
Implement SPARQL-WG decision on blank node label use in update.
Fix rebulding algebra (leftjoin) from text form.

Modified:
    jena/trunk/jena-arq/Grammar/arq.jj
    jena/trunk/jena-arq/Grammar/master.jj
    jena/trunk/jena-arq/Grammar/sparql_11.jj
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserBase.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserQueryBase.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderOp.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/writers/WriterExpr.java
    jena/trunk/jena-arq/src/main/java/org/openjena/atlas/lib/FileOps.java

Modified: jena/trunk/jena-arq/Grammar/arq.jj
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/Grammar/arq.jj?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/Grammar/arq.jj (original)
+++ jena/trunk/jena-arq/Grammar/arq.jj Thu Oct  4 12:59:12 2012
@@ -260,7 +260,10 @@ String SourceSelector() : { String iri ;
 }
 void WhereClause() : { Element el ; }
 {
-   (<WHERE>)? el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   (<WHERE>)?
+   { startWherePattern() ; }
+   el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   { finishWherePattern() ; }
 }
 void SolutionModifier() : { }
 {
@@ -461,13 +464,18 @@ Update DeleteWhere() : { QuadAcc qp = ne
 Update Modify() : { Element el ; String iri = null ;
                     UpdateModify up = new UpdateModify() ; }
 {
+  { startModifyUpdate() ; }
   ( <WITH> iri = iri() { Node n = createNode(iri) ; up.setWithIRI(n) ; } )?
   ( DeleteClause(up) ( InsertClause(up) )?
   | InsertClause(up)
   )
   (UsingClause(up))*
+  // WHERE is mandatory here.
   <WHERE>
+  { startWherePattern() ; }
   el = GroupGraphPattern() { up.setElement(el) ; }
+  { finishWherePattern() ; }
+  { finishModifyUpdate() ; }
   { return up ; }
 }
 Update ModifyOld() :

Modified: jena/trunk/jena-arq/Grammar/master.jj
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/Grammar/master.jj?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/Grammar/master.jj (original)
+++ jena/trunk/jena-arq/Grammar/master.jj Thu Oct  4 12:59:12 2012
@@ -334,7 +334,10 @@ String SourceSelector() : { String iri ;
 
 void WhereClause() : { Element el ; }
 {
-   (<WHERE>)? el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   (<WHERE>)? 
+   { startWherePattern() ; }
+   el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   { finishWherePattern() ; }
 }
 
 void SolutionModifier() : { }
@@ -585,13 +588,18 @@ Update DeleteWhere() : { QuadAcc qp = ne
 Update Modify() : { Element el ; String iri = null ;
                     UpdateModify up = new UpdateModify() ; }
 {
+  { startModifyUpdate() ; }
   ( <WITH> iri = iri() { Node n = createNode(iri) ; up.setWithIRI(n) ; } )?
   ( DeleteClause(up) ( InsertClause(up) )?
   | InsertClause(up)
   )
   (UsingClause(up))*
+  // WHERE is mandatory here.
   <WHERE>
+  { startWherePattern() ; }
   el = GroupGraphPattern() { up.setElement(el) ; }    
+  { finishWherePattern() ; }
+  { finishModifyUpdate() ; }
   { return up ; }
 }
 

Modified: jena/trunk/jena-arq/Grammar/sparql_11.jj
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/Grammar/sparql_11.jj?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/Grammar/sparql_11.jj (original)
+++ jena/trunk/jena-arq/Grammar/sparql_11.jj Thu Oct  4 12:59:12 2012
@@ -247,7 +247,10 @@ String SourceSelector() : { String iri ;
 }
 void WhereClause() : { Element el ; }
 {
-   (<WHERE>)? el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   (<WHERE>)?
+   { startWherePattern() ; }
+   el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   { finishWherePattern() ; }
 }
 void SolutionModifier() : { }
 {
@@ -444,13 +447,18 @@ Update DeleteWhere() : { QuadAcc qp = ne
 Update Modify() : { Element el ; String iri = null ;
                     UpdateModify up = new UpdateModify() ; }
 {
+  { startModifyUpdate() ; }
   ( <WITH> iri = iri() { Node n = createNode(iri) ; up.setWithIRI(n) ; } )?
   ( DeleteClause(up) ( InsertClause(up) )?
   | InsertClause(up)
   )
   (UsingClause(up))*
+  // WHERE is mandatory here.
   <WHERE>
+  { startWherePattern() ; }
   el = GroupGraphPattern() { up.setElement(el) ; }
+  { finishWherePattern() ; }
+  { finishModifyUpdate() ; }
   { return up ; }
 }
 void DeleteClause(UpdateModify up) : { QuadAcc qp = up.getDeleteAcc() ; Token t ;}

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserBase.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserBase.java?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserBase.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserBase.java Thu Oct  4 12:59:12 2012
@@ -83,7 +83,7 @@ public class ParserBase
     //    BGP causes the map to be cleared at the start of the BGP
     
     LabelToNodeMap activeLabelMap = anonVarLabels ;
-    Set<String> oldLabels = new HashSet<String>() ; 
+    Set<String> previousLabels = new HashSet<String>() ; 
     
     //LabelToNodeMap listLabelMap = new LabelToNodeMap(true, new VarAlloc("L")) ;
     // ----
@@ -303,7 +303,7 @@ public class ParserBase
     { activeLabelMap.clear() ; }
 
     protected void endBasicGraphPattern()
-    { oldLabels.addAll(activeLabelMap.getLabels()) ; }
+    { previousLabels.addAll(activeLabelMap.getLabels()) ; }
     
     protected void startTriplesBlock()
     { }
@@ -344,8 +344,8 @@ public class ParserBase
     { 
         if ( ! bNodesAreAllowed )
             throwParseException("Blank nodes not allowed in DELETE templates: "+label, line, column) ;
-        if ( oldLabels.contains(label) )
-            throwParseException("Blank node reused across basic graph patterns: "+label,
+        if ( previousLabels.contains(label) )
+            throwParseException("Blank node label reuse not allowed at this point: "+label,
                                 line, column) ;
         
         //label = unescapeCodePoint(label, line, column) ;

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserQueryBase.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserQueryBase.java?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserQueryBase.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/ParserQueryBase.java Thu Oct  4 12:59:12 2012
@@ -23,12 +23,14 @@ import java.util.* ;
 import com.hp.hpl.jena.graph.Node ;
 import com.hp.hpl.jena.query.Query ;
 import com.hp.hpl.jena.query.QueryParseException ;
+import com.hp.hpl.jena.sparql.ARQInternalErrorException ;
 import com.hp.hpl.jena.sparql.core.Var ;
 import com.hp.hpl.jena.sparql.engine.binding.Binding ;
 import com.hp.hpl.jena.sparql.engine.binding.BindingFactory ;
 import com.hp.hpl.jena.sparql.engine.binding.BindingMap ;
 import com.hp.hpl.jena.sparql.modify.request.QuadAcc ;
 import com.hp.hpl.jena.sparql.modify.request.QuadDataAcc ;
+import com.hp.hpl.jena.sparql.util.LabelToNodeMap ;
 import com.hp.hpl.jena.update.Update ;
 import com.hp.hpl.jena.update.UpdateRequest ;
 
@@ -63,6 +65,17 @@ public class ParserQueryBase extends Par
     // SPARQL Update (W3C RECommendation)
     private UpdateRequest request = null ;
 
+    // Places to push settings across points where we reset.
+    private boolean oldBNodesAreVariables ;
+    private boolean oldBNodesAreAllowed ;
+
+    // Count of subSelect nesting.
+    // Level 0 is top level.
+    // Level -1 is not in a pattern WHERE clause.
+    private int queryLevel = -1 ;
+    private Deque<Set<String>>    stackPreviousLabels = new ArrayDeque<Set<String>>() ;
+    private Deque<LabelToNodeMap> stackCurrentLabels = new ArrayDeque<LabelToNodeMap>() ;
+
     protected UpdateRequest getUpdateRequest() { return request ; }
     public void setUpdateRequest(UpdateRequest request)
     { 
@@ -70,25 +83,27 @@ public class ParserQueryBase extends Par
         this.query = new Query() ; 
         setPrologue(request) ;
     }
+
+    // Signal start/finish of units
     
-    // Move down to SPARQL 1.1 or rename as ParserBase
     protected void startQuery() {}
     protected void finishQuery() {}
 
+    protected void startUpdateRequest()    {}
+    protected void finishUpdateRequest()   {}
+    
 //    protected void startBasicGraphPattern()
 //    { activeLabelMap.clear() ; }
 //
 //    protected void endBasicGraphPattern()
 //    { oldLabels.addAll(activeLabelMap.getLabels()) ; }
     
-    // Move down to SPARQL 1.1 or rename as ParserBase
-    protected void startUpdateOperation() {}
+    protected void startUpdateOperation()  {}
     protected void finishUpdateOperation() {}
     
-    protected void startUpdateRequest() {}
-    protected void finishUpdateRequest() {}
+    protected void startModifyUpdate()     { }
+    protected void finishModifyUpdate()    {}
     
-    private boolean oldBNodesAreVariables ;
     protected void startDataInsert(QuadDataAcc qd, int line, int col) 
     {
         oldBNodesAreVariables = getBNodesAreVariables() ;
@@ -98,13 +113,11 @@ public class ParserQueryBase extends Par
     
     protected void finishDataInsert(QuadDataAcc qd, int line, int col)
     {
-        oldLabels.addAll(activeLabelMap.getLabels()) ;
+        previousLabels.addAll(activeLabelMap.getLabels()) ;
         activeLabelMap.clear() ;
         setBNodesAreVariables(oldBNodesAreVariables) ;
     }
     
-    private boolean oldBNodesAreAllowed ;
-    
     protected void startDataDelete(QuadDataAcc qd,int line, int col)
     {
         oldBNodesAreAllowed = getBNodesAreAllowed() ;
@@ -115,26 +128,44 @@ public class ParserQueryBase extends Par
     {
         setBNodesAreAllowed(oldBNodesAreAllowed) ;
     }
+
+    // These can be nested with subSELECTs but subSELECTs share bNodeLabel state.
+    protected void startWherePattern()
+    {
+        queryLevel += 1 ;
+        if ( queryLevel == 0 )
+        {
+            pushLabelState() ;
+            clearLabelState() ;
+        }
+    }
     
-    Set<String> oldLabels2 = null ;
-    
+    protected void finishWherePattern()
+    {
+        if ( queryLevel == 0 )
+            popLabelState() ;
+        queryLevel -= 1 ;
+    }
+
+    // This holds the accumulation of labels from earlier INSERT DATA
+    // across template creation (bNode in templates get cloned before
+    // going into the data).
+
     protected void startInsertTemplate(QuadAcc qd, int line, int col)
     {
         oldBNodesAreVariables = getBNodesAreVariables() ;
         setBNodesAreVariables(false) ;
-        // Hide used labels (INSERT DATA)
-        oldLabels2 = oldLabels ;
-        oldLabels = new HashSet<String>() ;
-        activeLabelMap.clear() ;
+        pushLabelState() ;
     }
-    
+
     protected void finishInsertTemplate(QuadAcc qd, int line, int col)
     {
         setBNodesAreVariables(oldBNodesAreVariables) ;
-        oldLabels = oldLabels2 ;
-        activeLabelMap.clear() ;
+        // Restore accumulated labels. 
+        popLabelState() ;
     }
     
+    // No bNodes in delete templates.
     protected void startDeleteTemplate(QuadAcc qd, int line, int col)
     {
         oldBNodesAreAllowed = getBNodesAreAllowed() ;
@@ -154,11 +185,9 @@ public class ParserQueryBase extends Par
     protected void startSubSelect(int line, int col)
     {
         if ( query == null )
-            System.out.println("Null") ;
-        // Query is null in an update.
+            throw new ARQInternalErrorException("Parser query object is null") ;
         stack.push(query) ;
-        Query subQuery = new Query(getPrologue()) ;
-        query = subQuery ;
+        query = new Query(getPrologue()) ;
     }
     
     protected Query endSubSelect(int line, int column)
@@ -229,4 +258,25 @@ public class ParserQueryBase extends Par
             throw new QueryParseException(msg, line , col) ;
         }
     }
+
+    private void pushLabelState()
+    { 
+        // Hide used labels already tracked.
+        stackPreviousLabels.push(previousLabels) ;
+        stackCurrentLabels.push(activeLabelMap) ;
+        previousLabels = new HashSet<String>() ;
+        activeLabelMap.clear() ;
+    }
+
+    private void popLabelState()
+    {
+        previousLabels = stackPreviousLabels.pop() ;
+        activeLabelMap = stackCurrentLabels.pop();
+    }
+
+    private void clearLabelState()
+    {
+        activeLabelMap.clear() ;
+        previousLabels.clear() ;
+    }
 }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java Thu Oct  4 12:59:12 2012
@@ -734,8 +734,10 @@ public class ARQParser extends ARQParser
       jj_la1[21] = jj_gen;
       ;
     }
+     startWherePattern() ;
     el = GroupGraphPattern();
-                                         getQuery().setQueryPattern(el) ;
+                              getQuery().setQueryPattern(el) ;
+     finishWherePattern() ;
   }
 
   final public void SolutionModifier() throws ParseException {
@@ -1660,6 +1662,7 @@ public class ARQParser extends ARQParser
   final public Update Modify() throws ParseException {
                     Element el ; String iri = null ;
                     UpdateModify up = new UpdateModify() ;
+    startModifyUpdate() ;
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
     case WITH:
       jj_consume_token(WITH);
@@ -1703,8 +1706,11 @@ public class ARQParser extends ARQParser
       UsingClause(up);
     }
     jj_consume_token(WHERE);
+    startWherePattern() ;
     el = GroupGraphPattern();
                              up.setElement(el) ;
+    finishWherePattern() ;
+    finishModifyUpdate() ;
     {if (true) return up ;}
     throw new Error("Missing return statement in function");
   }
@@ -5535,12 +5541,6 @@ public class ARQParser extends ARQParser
     finally { jj_save(3, xla); }
   }
 
-  private boolean jj_3R_109() {
-    if (jj_scan_token(NOT)) return true;
-    if (jj_scan_token(EXISTS)) return true;
-    return false;
-  }
-
   private boolean jj_3R_128() {
     if (jj_scan_token(LBRACKET)) return true;
     return false;
@@ -5584,11 +5584,6 @@ public class ARQParser extends ARQParser
     return false;
   }
 
-  private boolean jj_3_1() {
-    if (jj_3R_40()) return true;
-    return false;
-  }
-
   private boolean jj_3R_107() {
     if (jj_scan_token(REGEX)) return true;
     if (jj_scan_token(LPAREN)) return true;
@@ -5600,6 +5595,11 @@ public class ARQParser extends ARQParser
     return false;
   }
 
+  private boolean jj_3_1() {
+    if (jj_3R_40()) return true;
+    return false;
+  }
+
   private boolean jj_3R_98() {
     if (jj_3R_109()) return true;
     return false;
@@ -6571,6 +6571,12 @@ public class ARQParser extends ARQParser
     return false;
   }
 
+  private boolean jj_3R_109() {
+    if (jj_scan_token(NOT)) return true;
+    if (jj_scan_token(EXISTS)) return true;
+    return false;
+  }
+
   /** Generated Token Manager. */
   public ARQParserTokenManager token_source;
   JavaCharStream jj_input_stream;

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java Thu Oct  4 12:59:12 2012
@@ -442,8 +442,10 @@ public class SPARQLParser11 extends SPAR
       jj_la1[19] = jj_gen;
       ;
     }
+     startWherePattern() ;
     el = GroupGraphPattern();
-                                         getQuery().setQueryPattern(el) ;
+                              getQuery().setQueryPattern(el) ;
+     finishWherePattern() ;
   }
 
   final public void SolutionModifier() throws ParseException {
@@ -1336,6 +1338,7 @@ public class SPARQLParser11 extends SPAR
   final public Update Modify() throws ParseException {
                     Element el ; String iri = null ;
                     UpdateModify up = new UpdateModify() ;
+    startModifyUpdate() ;
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
     case WITH:
       jj_consume_token(WITH);
@@ -1379,8 +1382,11 @@ public class SPARQLParser11 extends SPAR
       UsingClause(up);
     }
     jj_consume_token(WHERE);
+    startWherePattern() ;
     el = GroupGraphPattern();
                              up.setElement(el) ;
+    finishWherePattern() ;
+    finishModifyUpdate() ;
     {if (true) return up ;}
     throw new Error("Missing return statement in function");
   }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderOp.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderOp.java?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderOp.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderOp.java Thu Oct  4 12:59:12 2012
@@ -197,25 +197,6 @@ public class BuilderOp
         return triples ;
     }
     
-    public static Expr buildExpr(Item item)
-    {
-        return BuilderExpr.buildExpr(item) ;
-    }
-
-    // Build a list of expressions.
-    public static List<Expr> buildExpr(ItemList list)
-    {
-        List<Expr> x = new ArrayList<Expr>() ;
-        for ( int i = 0 ; i < list.size() ; i++ )
-        {
-            Item itemExpr = list.get(i) ;
-            Expr expr = buildExpr(itemExpr) ;
-            x.add(expr) ;
-        }
-        return x ;
-    }
-
-
     protected Op build(ItemList list, int idx)
     {
         return build(list.get(idx).getList()) ;
@@ -402,7 +383,7 @@ public class BuilderOp
             BuilderLib.checkLength(3, 4, list, "leftjoin: wanted 2 or 3 arguments") ;
             Op left = build(list, 1) ;
             Op right  = build(list, 2) ;
-            Expr expr = null ;
+            ExprList expr = null ;
             if ( list.size() == 4 )
             {
                 Item exprItem = list.get(3) ;
@@ -410,7 +391,7 @@ public class BuilderOp
                 if ( exprItem.isList() && exprItem.getList().isEmpty() )
                 {}
                 else
-                    expr = buildExpr(exprItem) ;
+                    expr = BuilderExpr.buildExprOrExprList(exprItem) ;
             }
             Op op = OpLeftJoin.create(left, right, expr) ;
             return op ;

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/writers/WriterExpr.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/writers/WriterExpr.java?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/writers/WriterExpr.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/writers/WriterExpr.java Thu Oct  4 12:59:12 2012
@@ -33,6 +33,7 @@ import com.hp.hpl.jena.sparql.expr.ExprV
 import com.hp.hpl.jena.sparql.expr.ExprVisitorFunction ;
 import com.hp.hpl.jena.sparql.expr.NodeValue ;
 import com.hp.hpl.jena.sparql.serializer.SerializationContext ;
+import com.hp.hpl.jena.sparql.sse.Tags ;
 
 public class WriterExpr
 {
@@ -63,10 +64,12 @@ public class WriterExpr
             return ;
         }
         
+        out.print("(") ;
         if ( withTag )
-            out.print("(exprlist ") ;
-        else
-            out.print("(") ;
+        {
+            out.print(Tags.tagExprList) ;
+            out.print(" ") ;
+        }
         
         for ( int i = 0 ; i < exprs.size() ;  i++ )
         {

Modified: jena/trunk/jena-arq/src/main/java/org/openjena/atlas/lib/FileOps.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/openjena/atlas/lib/FileOps.java?rev=1394034&r1=1394033&r2=1394034&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/openjena/atlas/lib/FileOps.java (original)
+++ jena/trunk/jena-arq/src/main/java/org/openjena/atlas/lib/FileOps.java Thu Oct  4 12:59:12 2012
@@ -98,7 +98,7 @@ public class FileOps
     {
         File dir = new File(dirname) ;
         if ( ! dir.exists() )
-            dir.mkdir() ;
+            dir.mkdirs() ;
     }
     
     /** Split a file name into path, basename and extension.  Nulls returned if don't make sense. */