KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > xquery > reconstruction > ReconstructionVisitor


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  * Copyright (C) 2003 XQuark Group.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
19  * You can also get it at http://www.gnu.org/licenses/lgpl.html
20  *
21  * For more information on this software, see http://www.xquark.org.
22  */

23
24 package org.xquark.xquery.reconstruction;
25
26 import java.util.*;
27
28 import org.xml.sax.*;
29 import org.xml.sax.ext.LexicalHandler JavaDoc;
30 import org.xml.sax.helpers.AttributesImpl JavaDoc;
31 import org.xquark.schema.validation.PSVInfoSetProvider;
32 import org.xquark.schema.validation.ValidationContextProvider;
33 import org.xquark.util.NamespaceContextHandler;
34 import org.xquark.util.NamespaceContextStack;
35 import org.xquark.xml.xdbc.XMLDBCException;
36 import org.xquark.xquery.metadata.DynamicContext;
37 import org.xquark.xquery.parser.*;
38 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.FunctionDATA;
39 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.FunctionEXPANDED_QNAME;
40 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.FunctionQNAME;
41 import org.xquark.xquery.typing.QType;
42 import org.xquark.xquery.xdbc.XDBCResultSetInterface;
43 import org.xquark.xquery.xdbc.XResultSetImpl;
44
45 public class ReconstructionVisitor extends DefaultParserVisitor {
46
47     private static final String JavaDoc RCSRevision = "$Revision: 1.4 $";
48     private static final String JavaDoc RCSName = "$Name: $";
49
50     private final String JavaDoc EMPTY_STRING = "";
51     private final String JavaDoc WHITE_SPACE = " ";
52     static final private String JavaDoc PREFIXROOT = "xqns";
53
54     //private ContentHandler contenthandler = null;
55
//private LexicalHandler lexicalhandler = null;
56
private ErrorHandler errorhandler = null;
57     private ReconstructionHandler reconstructionHandler = null;
58
59     private XResultSetImpl resultSet = null;
60     private XDBCResultSetInterface xdbcResultSet = null;
61     private EvaluationVisitor evalVisitor = null;
62
63     private AttributesImpl JavaDoc listAttributes = null;
64
65     private Object JavaDoc[] lastIdentifiers = null;
66     private Object JavaDoc[] currentIdentifiers = null;
67     private Object JavaDoc[] nextIdentifiers = null;
68     private boolean noNext = false;
69     private boolean noReconstructor = false;
70     private boolean hasidentifiers = false;
71
72     private boolean hasPrefixMapping = false;
73     private NamespaceContextStack declaredDeclarations = null;
74     private NamespaceContextStack reconstructionDeclarations = new NamespaceContextStack();
75
76     private ValidationContextProvider vcp = new ValidationContextProvider() {
77         public String JavaDoc getNamespaceURI(String JavaDoc prefix) {
78             return reconstructionDeclarations.getNamespaceURI(prefix);
79         }
80         public String JavaDoc getPrefix(String JavaDoc uri) {
81             return reconstructionDeclarations.getPrefix(uri);
82         }
83         public String JavaDoc getDocumentBase() {
84             return null;
85         }
86         public Map getNotationDeclarations() {
87             return null;
88         }
89     };
90
91     private int size = -1;
92     private ArrayList varList = null;
93     private int lastSkolemIDsSize = -1;
94     private ArrayList lastDependIDs = null;
95
96     private boolean evalNeeded = false;
97     private String JavaDoc evalResultNamespace = null;
98     private String JavaDoc evalResultValue = null;
99
100     private boolean root = true;
101     private boolean noResultSet = false;
102     private boolean noReInit = false;
103     private ArrayList skolemIDs = null;
104
105     private DynamicContext dc = null;
106     private PSVInfoSetProvider psvisp = null;
107
108     private class ReconstructionHandler extends NamespaceContextHandler {
109         private final String JavaDoc WHITE_SPACE = " ";
110
111         private boolean prevIsOnlyChars = false;
112         private boolean isOnlyChars = false;
113
114         public boolean IsOnlyChars() {
115             return isOnlyChars;
116         }
117
118         public void reset(boolean prev) {
119             prevIsOnlyChars = prev;
120         }
121
122         public void characters(char[] values, int start, int length) throws SAXException {
123             if (prevIsOnlyChars) {
124                 super.characters(WHITE_SPACE.toCharArray(), 0, 1);
125             }
126             if (!isOnlyChars)
127                 isOnlyChars = true;
128             super.characters(values, start, length);
129         }
130
131         public void startElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname, Attributes attributes) throws SAXException {
132             contextStack.pushContext();
133             checkPrefix(uri);
134             for (int i = 0; i < attributes.getLength(); i++) {
135                 checkPrefix(attributes.getURI(i));
136             }
137             super.startElement(uri, localname, qname, attributes);
138             if (isOnlyChars)
139                 isOnlyChars = false;
140             if (prevIsOnlyChars)
141                 prevIsOnlyChars = false;
142         }
143
144         private void checkPrefix(String JavaDoc uri) throws SAXException {
145             if (uri == null || uri.length() == 0)
146                 return;
147             if (getPrefix(uri) == null) {
148                 String JavaDoc prefix = (declaredDeclarations == null) ? null : declaredDeclarations.getPrefix(uri);
149                 if (prefix == null) {
150                     for (int i = 1;; i++) {
151                         String JavaDoc genPrefix = PREFIXROOT + i;
152                         if (getNamespaceURI(genPrefix) == null) {
153                             prefix = genPrefix;
154                             break;
155                         }
156                     }
157                 }
158                 this.startPrefixMapping(prefix, uri);
159             }
160         }
161
162         public void processingInstruction(String JavaDoc str, String JavaDoc str1) throws SAXException {
163             super.processingInstruction(str, str1);
164             if (isOnlyChars)
165                 isOnlyChars = false;
166             if (prevIsOnlyChars)
167                 prevIsOnlyChars = false;
168         }
169
170         public void endElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname) throws SAXException {
171             super.endElement(uri, localname, qname);
172             List list = contextStack.getDeclaredPrefixes();
173             for (int i = 0; i < list.size(); i++)
174                 this.endPrefixMapping((String JavaDoc) list.get(i));
175             contextStack.popContext();
176             if (isOnlyChars)
177                 isOnlyChars = false;
178             if (prevIsOnlyChars)
179                 prevIsOnlyChars = false;
180         }
181     }
182
183     public ReconstructionVisitor(XResultSetImpl resultSet, ArrayList varList) {
184         this.reconstructionHandler = new ReconstructionHandler();
185         this.resultSet = resultSet;
186         this.xdbcResultSet = resultSet.getXDBCResultSet();
187         if (xdbcResultSet != null) {
188             xdbcResultSet.setContentHandler(reconstructionHandler);
189             xdbcResultSet.setLexicalHandler(reconstructionHandler);
190         }
191         psvisp = resultSet.getPSVInfoSetProvider();
192         this.varList = varList;
193         size = varList.size();
194         currentIdentifiers = new Object JavaDoc[size];
195         nextIdentifiers = new Object JavaDoc[size];
196         lastIdentifiers = new Object JavaDoc[size];
197         listAttributes = new AttributesImpl JavaDoc();
198         evalVisitor = new EvaluationVisitor(xdbcResultSet, vcp);
199     }
200
201     public void reInit() {
202         if (!noReInit)
203             noNext = false;
204         else
205             noReInit = false;
206         root = true;
207         hasPrefixMapping = false;
208         hasidentifiers = false;
209     }
210
211     private void setIdentifiers(boolean force) throws XQueryException {
212         if (!force && hasidentifiers)
213             return;
214         try {
215             if (xdbcResultSet.hasNext())
216                 xdbcResultSet.getNextIdentifiers(nextIdentifiers);
217             if (!this.noResultSet)
218                 xdbcResultSet.getIdentifiers(currentIdentifiers);
219             hasidentifiers = true;
220         } catch (XMLDBCException xmldbce) {
221             throw new XQueryException(xmldbce.getMessage());
222         }
223     }
224
225     public void setContentHandler(ContentHandler handler) {
226         reconstructionHandler.setContentHandler(handler);
227         if (xdbcResultSet != null)
228             xdbcResultSet.setContentHandler(reconstructionHandler);
229     }
230
231     /**
232      * @see XDBCResultSetInterface#setLexicalHandler
233      */

234     public void setLexicalHandler(LexicalHandler JavaDoc handler) {
235         reconstructionHandler.setLexicalHandler(handler);
236         if (xdbcResultSet != null)
237             xdbcResultSet.setLexicalHandler(reconstructionHandler);
238     }
239
240     /**
241      * @see XDBCResultSetInterface#setErrorHandler
242      */

243     public void setErrorHandler(ErrorHandler handler) {
244         errorhandler = handler;
245     }
246
247     public XResultSetImpl getResultSet() {
248         return resultSet;
249     }
250     /*
251     public ContentHandler getContentHandler() {
252         return reconstructionHandler.getContentHandler();
253     }
254     public LexicalHandler getLexicalHandler() {
255         return reconstructionHandler.getLexicalHandler();
256     }
257     public ErrorHandler getErrorHandler() {
258         return errorhandler;
259     }
260     */

261     public boolean getNoReconstructor() {
262         return noReconstructor;
263     }
264     public boolean getNoNext() {
265         return noNext;
266     }
267     public boolean getNoResultSet() {
268         return noResultSet;
269     }
270     public void setNoResultSet(boolean noResultSet) {
271         this.noResultSet = noResultSet;
272     }
273     public void setNamespaceDecl(NamespaceContextStack declarations) {
274         hasPrefixMapping = true;
275         this.declaredDeclarations = declarations;
276     }
277     public void setDynamicContext(DynamicContext dc) {
278         this.dc = dc;
279         evalVisitor.setDynamicContext(dc);
280     }
281     // visitor ...
282

283     // public void visit(AggregateFunctionCall arg) throws XQueryException
284

285     private void outputAttributeValuePair(AttributeValuePair arg) throws XQueryException {
286         if (arg.isXmlns())
287             return;
288         String JavaDoc nameSpaceAtt = EMPTY_STRING;
289         String JavaDoc localNameAtt = EMPTY_STRING;
290         String JavaDoc value = EMPTY_STRING;
291         XQueryExpression attrName = arg.getAttributeName();
292         evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
293         attrName.accept(evalVisitor);
294         Comparable JavaDoc comp = evalVisitor.getResValue();
295         if (comp != null) {
296             // this is not nice but for now it works fine
297
String JavaDoc compStr = comp.toString();
298             if (compStr.startsWith("{")) {
299                 int ind = compStr.lastIndexOf('}');
300                 if (ind == -1)
301                     localNameAtt = compStr;
302                 else {
303                     nameSpaceAtt = compStr.substring(1, ind);
304                     localNameAtt = compStr.substring(ind + 1);
305                 }
306             } else {
307                 int ind = compStr.lastIndexOf(':');
308                 if (ind == -1)
309                     localNameAtt = compStr;
310                 else {
311                     String JavaDoc prefix = compStr.substring(0, ind);
312                     nameSpaceAtt = reconstructionDeclarations.getNamespaceURI(prefix);
313                     if (nameSpaceAtt == null) {
314                         if (declaredDeclarations != null)
315                             nameSpaceAtt = declaredDeclarations.getNamespaceURI(prefix);
316                         if (nameSpaceAtt != null)
317                             reconstructionDeclarations.declarePrefix(prefix, nameSpaceAtt);
318                     }
319                     localNameAtt = compStr.substring(ind + 1);
320                 }
321             }
322         }
323         XQueryExpression attrValue = arg.getAttributeValue();
324         evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
325         attrValue.accept(evalVisitor);
326         comp = evalVisitor.getResValue();
327         if (comp != null)
328             value = comp.toString();
329         // test if attribute already exists
330
if (listAttributes.getValue(nameSpaceAtt, localNameAtt) != null)
331             throw new ReconstructionException("An element cannot have several attributes with the same name.");
332         // add attribute
333
listAttributes.addAttribute((nameSpaceAtt == null ? "" : nameSpaceAtt), localNameAtt, "", "STRING", value);
334         // reset key variables
335
skolemIDs = arg.getSkolemIDs();
336         if (skolemIDs != null)
337             lastSkolemIDsSize = skolemIDs.size();
338     }
339
340     public void visit(AttributeValuePair arg) throws XQueryException {
341         if (arg.isXmlns())
342             return;
343         boolean isSkolemID = false;
344         boolean isDependID = false;
345         boolean putPrefixMapping = false;
346         noReconstructor = true;
347         skolemIDs = arg.getSkolemIDs();
348         if (skolemIDs != null)
349             lastSkolemIDsSize = skolemIDs.size();
350         if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
351             isSkolemID = true;
352         ArrayList dependIDs = arg.getDependIDs();
353         if (dependIDs != null && !dependIDs.isEmpty())
354             isDependID = true;
355         boolean loop = arg.getLoop();
356
357         // CASE : this element has no skolem ids
358
if (!isSkolemID) {
359             // CASE : the element is written until there are no more results available
360
if (loop) {
361                 // no not continue if dependIDs changed
362
if (this.noResultSet && dependIDs != lastDependIDs)
363                     return;
364                 while (true) {
365                     // WRITE SONS
366
boolean previousRoot = root;
367                     root = false;
368                     outputAttributeValuePair(arg);
369                     root = previousRoot;
370                     noReconstructor = true;
371                     if (hasNext())
372                         nextAsSAX();
373                     else
374                         break;
375                 }
376             }
377             // CASE : no loop and element has depend ids
378
else if (isDependID) {
379                 noNext = false;
380                 boolean changeDependIDs = true;
381                 /// !!! DANGER !!! THIS is stupid code!!! ( )
382
try {
383                     this.setIdentifiers(false);
384                 } catch (XQueryException e) {
385                     changeDependIDs = false;
386                 }
387                 while (!isEmpty(dependIDs) && changeDependIDs) {
388                     // WRITE SONS
389
boolean previousRoot = root;
390                     root = false;
391                     outputAttributeValuePair(arg);
392                     root = previousRoot;
393                     if (!hasNext())
394                         break;
395                     changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
396                     if (!changeDependIDs) {
397                         noNext = false;
398                         break;
399                     } else if (!isEmpty(dependIDs))
400                         noNext = false;
401                     if (!noNext) {
402                         noReconstructor = true;
403                         if (!hasNext())
404                             break;
405                         identifierCopy(currentIdentifiers, lastIdentifiers);
406                         nextAsSAX();
407                         this.setIdentifiers(true);
408                     }
409                     if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
410                         noNext = true;
411                 }
412             } else {
413                 // WRITE SONS
414
boolean previousRoot = root;
415                 root = false;
416                 outputAttributeValuePair(arg);
417                 root = previousRoot;
418             }
419         }
420         // there is at least a skolemID
421
else {
422
423             // set the current identifier and the next
424
if (isSkolemID && !arg.getRoot()) {
425                 this.setIdentifiers(false);
426             }
427             // there is no dependID
428
if (dependIDs == null && !arg.getRoot()) {
429                 // CODE NOT USED !!! AS FAR AS I CAN TELL
430
if (loop) {
431                     while (true) {
432                         // WRITE SONS
433
boolean previousRoot = root;
434                         root = false;
435                         outputAttributeValuePair(arg);
436                         root = previousRoot;
437                         noReconstructor = true;
438                         noNext = false;
439                         if (hasNext())
440                             nextAsSAX();
441                         else
442                             break;
443                     }
444                 } else {
445                     // WRITE SONS
446
boolean previousRoot = root;
447                     root = false;
448                     outputAttributeValuePair(arg);
449                     root = previousRoot;
450                 }
451             } else // dependIDs != null or arg element is root
452
{
453                 noNext = false;
454                 if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
455                     boolean changeDependIDs = true;
456                     boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
457                     // stop if the skolemIDs changed, and that dependIDs does not have an incidence
458
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
459                         return;
460                     }
461
462                     int firstDependIDPosition = 0;
463                     if (dependIDs != null && !dependIDs.isEmpty()) {
464                         firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
465                     }
466                     int skipEntries = -1;
467                     if (firstDependIDPosition > skolemIDs.size()) {
468                         skipEntries = lastSkolemIDsSize;
469                         while (!changeSkolemIDs && isEmpty(dependIDs)) {
470                             if (!hasNext())
471                                 break;
472                             identifierCopy(currentIdentifiers, lastIdentifiers);
473                             nextAsSAX();
474                             this.setIdentifiers(true);
475                             changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
476                             changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
477                         }
478                     }
479                     while (!isEmpty(dependIDs) && changeDependIDs) {
480                         // WRITE SONS
481
boolean previousRoot = root;
482                         root = false;
483                         outputAttributeValuePair(arg);
484                         root = previousRoot;
485                         if (!hasNext())
486                             break;
487                         if (skipEntries == -1) {
488                             changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
489                             if (!changeDependIDs) {
490                                 noNext = false;
491                                 break;
492                             } else if (!isEmpty(dependIDs))
493                                 noNext = false;
494                         }
495                         // ----------------------------
496
// ADDED
497
//-----------------------------
498
else {
499                             changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
500                             changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
501                             if (!changeSkolemIDs) {
502                                 noNext = false;
503                                 boolean noDependIDs = true;
504                                 boolean makeBreak = false;
505                                 noReInit = false;
506                                 while (!changeSkolemIDs && noDependIDs) {
507                                     noReconstructor = true;
508                                     if (!hasNext()) {
509                                         makeBreak = true;
510                                         break;
511                                     }
512                                     identifierCopy(currentIdentifiers, lastIdentifiers);
513                                     nextAsSAX();
514                                     this.setIdentifiers(true);
515                                     changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
516                                     noDependIDs = isEmpty(dependIDs);
517                                 }
518                                 if (makeBreak)
519                                     break;
520                                 noNext = true;
521                                 if (!noDependIDs)
522                                     noReInit = true;
523                                 changeDependIDs = true;
524                             } else if (!isEmpty(dependIDs))
525                                 noNext = false;
526                         }
527                         // ----------------------------
528
// END ADDED
529
//-----------------------------
530
if (!noNext && !changeSkolemIDs) {
531                             noReconstructor = true;
532                             if (!hasNext())
533                                 break;
534                             identifierCopy(currentIdentifiers, lastIdentifiers);
535                             nextAsSAX();
536                             this.setIdentifiers(true);
537                         }
538                         if (skipEntries == -1) {
539                             if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
540                                 noNext = true;
541                         } else {
542                             if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
543                                 noNext = false; // CHANGE 03/07/2002 was initially true
544
}
545                     }
546                 } else {
547                     boolean changeSkolemIDs = false;
548                     while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
549                         // set last dependIDs
550
lastDependIDs = dependIDs;
551                         // WRITE SONS
552
boolean previousRoot = root;
553                         root = false;
554                         outputAttributeValuePair(arg);
555                         root = previousRoot;
556                         if (!hasNext())
557                             break;
558                         if (!arg.getRoot())
559                             changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
560                         if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
561                             noReconstructor = true;
562                             if (!hasNext())
563                                 break;
564                             identifierCopy(currentIdentifiers, lastIdentifiers);
565                             nextAsSAX();
566                             this.setIdentifiers(true);
567                         }
568                         if (changeSkolemIDs)
569                             noNext = true;
570                         if (arg.getRoot())
571                             break;
572                     }
573                     // while (!changeSkolemIDs);
574
}
575                 // noNext = true;
576
}
577         }
578         noReconstructor = false;
579     }
580
581     // public void visit(BinOpANDExpression arg) throws XQueryException;
582
// public void visit(BinOpORExpression arg) throws XQueryException;
583
// public void visit(CastTreatExpression arg) throws XQueryException;
584

585     public void visit(CData arg) throws XQueryException {
586         try {
587             reconstructionHandler.startCDATA();
588             characters(arg.getCData().toCharArray(), 0, arg.getCData().length());
589             reconstructionHandler.endCDATA();
590         } catch (SAXException e) {
591             throw new XQueryException(e.getMessage());
592         }
593     }
594
595     // public void visit(ContextDeclaration arg) throws XQueryException;
596

597     private void outputComputedText(ComputedText arg) throws XQueryException {
598         evalNeeded = true;
599         arg.getExpression().accept(this);
600         evalNeeded = false;
601         if (evalResultValue != null) {
602             characters(evalResultValue.toCharArray(), 0, evalResultValue.length());
603             reconstructionHandler.reset(true);
604             evalResultValue = null;
605         }
606         // reset key variables
607
skolemIDs = arg.getSkolemIDs();
608         if (skolemIDs != null)
609             lastSkolemIDsSize = skolemIDs.size();
610     }
611
612     public void visit(ComputedText arg) throws XQueryException {
613
614         boolean isSkolemID = false;
615         boolean isDependID = false;
616         boolean putPrefixMapping = false;
617         noReconstructor = true;
618         skolemIDs = arg.getSkolemIDs();
619         if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
620             isSkolemID = true;
621         ArrayList dependIDs = arg.getDependIDs();
622         if (dependIDs != null && !dependIDs.isEmpty())
623             isDependID = true;
624         boolean loop = arg.getLoop();
625
626         // CASE : this element has no skolem ids
627
if (!isSkolemID) {
628             // CASE : the element is written until there are no more results available
629
if (loop) {
630                 // no not continue if dependIDs changed
631
if (this.noResultSet && dependIDs != lastDependIDs)
632                     return;
633                 while (true) {
634                     // WRITE SONS
635
boolean previousRoot = root;
636                     root = false;
637                     outputComputedText(arg);
638                     root = previousRoot;
639                     noReconstructor = true;
640                     if (hasNext())
641                         nextAsSAX();
642                     else
643                         break;
644                 }
645             }
646             // CASE : no loop and element has depend ids
647
else if (isDependID) {
648                 noNext = false;
649                 boolean changeDependIDs = true;
650                 /// !!! DANGER !!! THIS is stupid code!!! ( )
651
try {
652                     this.setIdentifiers(false);
653                 } catch (XQueryException e) {
654                     changeDependIDs = false;
655                 }
656                 while (!isEmpty(dependIDs) && changeDependIDs) {
657                     // WRITE SONS
658
boolean previousRoot = root;
659                     root = false;
660                     outputComputedText(arg);
661                     root = previousRoot;
662                     if (!hasNext())
663                         break;
664                     changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
665                     if (!changeDependIDs) {
666                         noNext = false;
667                         break;
668                     } else if (!isEmpty(dependIDs))
669                         noNext = false;
670                     if (!noNext) {
671                         noReconstructor = true;
672                         if (!hasNext())
673                             break;
674                         identifierCopy(currentIdentifiers, lastIdentifiers);
675                         nextAsSAX();
676                         this.setIdentifiers(true);
677                     }
678                     if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
679                         noNext = true;
680                 }
681             } else {
682                 // WRITE SONS
683
boolean previousRoot = root;
684                 root = false;
685                 outputComputedText(arg);
686                 root = previousRoot;
687             }
688         }
689         // there is at least a skolemID
690
else {
691
692             // set the current identifier and the next
693
if (isSkolemID && !arg.getRoot()) {
694                 this.setIdentifiers(false);
695             }
696             // there is no dependID
697
if (dependIDs == null && !arg.getRoot()) {
698                 // CODE NOT USED !!! AS FAR AS I CAN TELL
699
if (loop) {
700                     while (true) {
701                         // WRITE SONS
702
boolean previousRoot = root;
703                         root = false;
704                         outputComputedText(arg);
705                         root = previousRoot;
706                         noReconstructor = true;
707                         noNext = false;
708                         if (hasNext())
709                             nextAsSAX();
710                         else
711                             break;
712                     }
713                 } else {
714                     // WRITE SONS
715
boolean previousRoot = root;
716                     root = false;
717                     outputComputedText(arg);
718                     root = previousRoot;
719                 }
720             } else // dependIDs != null or arg element is root
721
{
722                 noNext = false;
723                 if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
724                     boolean changeDependIDs = true;
725                     boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
726                     // stop if the skolemIDs changed, and that dependIDs does not have an incidence
727
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
728                         return;
729                     }
730
731                     int firstDependIDPosition = 0;
732                     if (dependIDs != null && !dependIDs.isEmpty()) {
733                         firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
734                     }
735                     int skipEntries = -1;
736                     if (firstDependIDPosition > skolemIDs.size()) {
737                         skipEntries = lastSkolemIDsSize;
738                         while (!changeSkolemIDs && isEmpty(dependIDs)) {
739                             if (!hasNext())
740                                 break;
741                             identifierCopy(currentIdentifiers, lastIdentifiers);
742                             nextAsSAX();
743                             this.setIdentifiers(true);
744                             changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
745                             changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
746                         }
747                     }
748                     while (!isEmpty(dependIDs) && changeDependIDs) {
749                         // WRITE SONS
750
boolean previousRoot = root;
751                         root = false;
752                         outputComputedText(arg);
753                         root = previousRoot;
754                         if (!hasNext())
755                             break;
756                         if (skipEntries == -1) {
757                             changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
758                             if (!changeDependIDs) {
759                                 noNext = false;
760                                 break;
761                             } else if (!isEmpty(dependIDs))
762                                 noNext = false;
763                         }
764                         // ----------------------------
765
// ADDED
766
//-----------------------------
767
else {
768                             changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
769                             changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
770                             if (!changeSkolemIDs) {
771                                 noNext = false;
772                                 boolean noDependIDs = true;
773                                 boolean makeBreak = false;
774                                 noReInit = false;
775                                 while (!changeSkolemIDs && noDependIDs) {
776                                     noReconstructor = true;
777                                     if (!hasNext()) {
778                                         makeBreak = true;
779                                         break;
780                                     }
781                                     identifierCopy(currentIdentifiers, lastIdentifiers);
782                                     nextAsSAX();
783                                     this.setIdentifiers(true);
784                                     changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
785                                     noDependIDs = isEmpty(dependIDs);
786                                 }
787                                 if (makeBreak)
788                                     break;
789                                 noNext = true;
790                                 if (!noDependIDs)
791                                     noReInit = true;
792                                 changeDependIDs = true;
793                             } else if (!isEmpty(dependIDs))
794                                 noNext = false;
795                         }
796                         // ----------------------------
797
// END ADDED
798
//-----------------------------
799
if (!noNext && !changeSkolemIDs) {
800                             noReconstructor = true;
801                             if (!hasNext())
802                                 break;
803                             identifierCopy(currentIdentifiers, lastIdentifiers);
804                             nextAsSAX();
805                             this.setIdentifiers(true);
806                         }
807                         if (skipEntries == -1) {
808                             if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
809                                 noNext = true;
810                         } else {
811                             if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
812                                 noNext = false; // CHANGE 03/07/2002 was initially true
813
}
814                     }
815                 } else {
816                     boolean changeSkolemIDs = false;
817                     while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
818                         // set last dependIDs
819
lastDependIDs = dependIDs;
820                         // WRITE SONS
821
boolean previousRoot = root;
822                         root = false;
823                         arg.getExpression().setRoot(true);
824                         outputComputedText(arg);
825                         root = previousRoot;
826                         if (!hasNext())
827                             break;
828                         if (!arg.getRoot())
829                             changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
830                         if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
831                             noReconstructor = true;
832                             if (!hasNext())
833                                 break;
834                             identifierCopy(currentIdentifiers, lastIdentifiers);
835                             nextAsSAX();
836                             this.setIdentifiers(true);
837                         }
838                         if (changeSkolemIDs)
839                             noNext = true;
840                         if (arg.getRoot())
841                             break;
842                     }
843                     // while (!changeSkolemIDs);
844
}
845                 // noNext = true;
846
}
847         }
848         noReconstructor = false;
849     }
850
851     // public void visit(Dereference arg) throws XQueryException;
852

853     private void outputDocument(Document arg) throws XQueryException {
854         arg.getExpression().accept(this);
855         // reset key variables
856
skolemIDs = arg.getSkolemIDs();
857         if (skolemIDs != null)
858             lastSkolemIDsSize = skolemIDs.size();
859     }
860
861     public void visit(Document arg) throws XQueryException {
862
863         boolean isSkolemID = false;
864         boolean isDependID = false;
865         boolean putPrefixMapping = false;
866         noReconstructor = true;
867         skolemIDs = arg.getSkolemIDs();
868         if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
869             isSkolemID = true;
870         ArrayList dependIDs = arg.getDependIDs();
871         if (dependIDs != null && !dependIDs.isEmpty())
872             isDependID = true;
873         boolean loop = arg.getLoop();
874
875         // CASE : this element has no skolem ids
876
if (!isSkolemID) {
877             // CASE : the element is written until there are no more results available
878
if (loop) {
879                 // no not continue if dependIDs changed
880
if (this.noResultSet && dependIDs != lastDependIDs)
881                     return;
882                 while (true) {
883                     try {
884                         reconstructionHandler.startDocument();
885                     } catch (SAXException e) {
886                         throw new XQueryException(e.getMessage());
887                     }
888                     // WRITE SONS
889
boolean previousRoot = root;
890                     root = false;
891                     outputDocument(arg);
892                     root = previousRoot;
893                     // WRITE STOP
894
try {
895                         reconstructionHandler.endDocument();
896                     } catch (SAXException e) {
897                         throw new XQueryException(e.getMessage());
898                     }
899                     noReconstructor = true;
900                     if (hasNext())
901                         nextAsSAX();
902                     else
903                         break;
904                 }
905             }
906             // CASE : no loop and element has depend ids
907
else if (isDependID) {
908                 noNext = false;
909                 boolean changeDependIDs = true;
910                 /// !!! DANGER !!! THIS is stupid code!!! ( )
911
try {
912                     this.setIdentifiers(false);
913                 } catch (XQueryException e) {
914                     changeDependIDs = false;
915                 }
916                 while (!isEmpty(dependIDs) && changeDependIDs) {
917                     // case of namespace in top element
918
try {
919                         reconstructionHandler.startDocument();
920                     } catch (SAXException e) {
921                         throw new XQueryException(e.getMessage());
922                     }
923                     // WRITE SONS
924
boolean previousRoot = root;
925                     root = false;
926                     outputDocument(arg);
927                     root = previousRoot;
928                     // WRITE STOP
929
try {
930                         reconstructionHandler.endDocument();
931                     } catch (SAXException e) {
932                         throw new XQueryException(e.getMessage());
933                     }
934                     if (!hasNext())
935                         break;
936                     changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
937                     if (!changeDependIDs) {
938                         noNext = false;
939                         break;
940                     } else if (!isEmpty(dependIDs))
941                         noNext = false;
942                     if (!noNext) {
943                         noReconstructor = true;
944                         if (!hasNext())
945                             break;
946                         identifierCopy(currentIdentifiers, lastIdentifiers);
947                         nextAsSAX();
948                         this.setIdentifiers(true);
949                     }
950                     if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
951                         noNext = true;
952                 }
953             } else {
954                 try {
955                     reconstructionHandler.startDocument();
956                 } catch (SAXException e) {
957                     throw new XQueryException(e.getMessage());
958                 }
959                 // WRITE SONS
960
boolean previousRoot = root;
961                 root = false;
962                 outputDocument(arg);
963                 root = previousRoot;
964                 // WRITE STOP
965
try {
966                     reconstructionHandler.endDocument();
967                 } catch (SAXException e) {
968                     throw new XQueryException(e.getMessage());
969                 }
970             }
971         }
972         // there is at least a skolemID
973
else {
974
975             // set the current identifier and the next
976
if (isSkolemID && !arg.getRoot()) {
977                 this.setIdentifiers(false);
978             }
979             // there is no dependID
980
if (dependIDs == null && !arg.getRoot()) {
981                 // CODE NOT USED !!! AS FAR AS I CAN TELL
982
if (loop) {
983                     while (true) {
984                         try {
985                             reconstructionHandler.startDocument();
986                         } catch (SAXException e) {
987                             throw new XQueryException(e.getMessage());
988                         }
989                         // WRITE SONS
990
boolean previousRoot = root;
991                         root = false;
992                         outputDocument(arg);
993                         root = previousRoot;
994                         // WRITE STOP
995
try {
996                             reconstructionHandler.endDocument();
997                         } catch (SAXException e) {
998                             throw new XQueryException(e.getMessage());
999                         }
1000                        noReconstructor = true;
1001                        noNext = false;
1002                        if (hasNext())
1003                            nextAsSAX();
1004                        else
1005                            break;
1006                    }
1007                } else {
1008                    try {
1009                        reconstructionHandler.startDocument();
1010                    } catch (SAXException e) {
1011                        throw new XQueryException(e.getMessage());
1012                    }
1013                    // WRITE SONS
1014
boolean previousRoot = root;
1015                    root = false;
1016                    outputDocument(arg);
1017                    root = previousRoot;
1018                    // WRITE STOP
1019
try {
1020                        reconstructionHandler.endDocument();
1021                    } catch (SAXException e) {
1022                        throw new XQueryException(e.getMessage());
1023                    }
1024                }
1025            } else // dependIDs != null or arg element is root
1026
{
1027                noNext = false;
1028                if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
1029                    boolean changeDependIDs = true;
1030
1031                    boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
1032                    // stop if the skolemIDs changed, and that dependIDs does not have an incidence
1033
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
1034                        return;
1035                    }
1036
1037                    int firstDependIDPosition = 0;
1038                    if (dependIDs != null && !dependIDs.isEmpty()) {
1039                        firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
1040                    }
1041                    int skipEntries = -1;
1042                    if (firstDependIDPosition > skolemIDs.size()) {
1043                        skipEntries = lastSkolemIDsSize;
1044                        while (!changeSkolemIDs && isEmpty(dependIDs)) {
1045                            if (!hasNext())
1046                                break;
1047                            identifierCopy(currentIdentifiers, lastIdentifiers);
1048                            nextAsSAX();
1049                            this.setIdentifiers(true);
1050                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
1051                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
1052                        }
1053                    }
1054                    while (!isEmpty(dependIDs) && changeDependIDs) {
1055                        try {
1056                            reconstructionHandler.startDocument();
1057                        } catch (SAXException e) {
1058                            throw new XQueryException(e.getMessage());
1059                        }
1060                        // WRITE SONS
1061
boolean previousRoot = root;
1062                        root = false;
1063                        outputDocument(arg);
1064                        root = previousRoot;
1065                        // WRITE STOP
1066
try {
1067                            reconstructionHandler.endDocument();
1068                        } catch (SAXException e) {
1069                            throw new XQueryException(e.getMessage());
1070                        }
1071                        if (!hasNext())
1072                            break;
1073                        if (skipEntries == -1) {
1074                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
1075                            if (!changeDependIDs) {
1076                                noNext = false;
1077                                break;
1078                            } else if (!isEmpty(dependIDs))
1079                                noNext = false;
1080                        }
1081                        // ----------------------------
1082
// ADDED
1083
//-----------------------------
1084
else {
1085                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
1086                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
1087                            if (!changeSkolemIDs) {
1088                                noNext = false;
1089                                boolean noDependIDs = true;
1090                                boolean makeBreak = false;
1091                                noReInit = false;
1092                                while (!changeSkolemIDs && noDependIDs) {
1093                                    noReconstructor = true;
1094                                    if (!hasNext()) {
1095                                        makeBreak = true;
1096                                        break;
1097                                    }
1098                                    identifierCopy(currentIdentifiers, lastIdentifiers);
1099                                    nextAsSAX();
1100                                    this.setIdentifiers(true);
1101                                    changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
1102                                    noDependIDs = isEmpty(dependIDs);
1103                                }
1104                                if (makeBreak)
1105                                    break;
1106                                noNext = true;
1107                                if (!noDependIDs)
1108                                    noReInit = true;
1109                                changeDependIDs = true;
1110                            } else if (!isEmpty(dependIDs))
1111                                noNext = false;
1112                        }
1113                        // ----------------------------
1114
// END ADDED
1115
//-----------------------------
1116
if (!noNext && !changeSkolemIDs) {
1117                            noReconstructor = true;
1118                            if (!hasNext())
1119                                break;
1120                            identifierCopy(currentIdentifiers, lastIdentifiers);
1121                            nextAsSAX();
1122                            this.setIdentifiers(true);
1123                        }
1124                        if (skipEntries == -1) {
1125                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
1126                                noNext = true;
1127                        } else {
1128                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
1129                                noNext = false; // CHANGE 03/07/2002 was initially true
1130
}
1131                    }
1132                } else {
1133                    boolean changeSkolemIDs = false;
1134                    while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
1135                        try {
1136                            reconstructionHandler.startDocument();
1137                        } catch (SAXException e) {
1138                            throw new XQueryException(e.getMessage());
1139                        }
1140                        // set last dependIDs
1141
lastDependIDs = dependIDs;
1142                        // WRITE SONS
1143
boolean previousRoot = root;
1144                        root = false;
1145                        arg.getExpression().setRoot(true);
1146                        outputDocument(arg);
1147                        root = previousRoot;
1148                        // WRITE STOP
1149
try {
1150                            reconstructionHandler.endDocument();
1151                        } catch (SAXException e) {
1152                            throw new XQueryException(e.getMessage());
1153                        }
1154                        if (!hasNext())
1155                            break;
1156                        if (!arg.getRoot())
1157                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
1158                        if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
1159                            noReconstructor = true;
1160                            if (!hasNext())
1161                                break;
1162                            identifierCopy(currentIdentifiers, lastIdentifiers);
1163                            nextAsSAX();
1164                            this.setIdentifiers(true);
1165                        }
1166                        if (changeSkolemIDs)
1167                            noNext = true;
1168                        if (arg.getRoot())
1169                            break;
1170                    }
1171                    // while (!changeSkolemIDs);
1172
}
1173                // noNext = true;
1174
}
1175        }
1176        noReconstructor = false;
1177    }
1178
1179    public void visit(Element arg) throws XQueryException {
1180
1181        if (evalNeeded) {
1182            evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
1183            arg.accept(evalVisitor);
1184            evalResultNamespace = EMPTY_STRING;
1185            Comparable JavaDoc comp = evalVisitor.getResValue();
1186            if (comp == null)
1187                evalResultValue = EMPTY_STRING;
1188            else {
1189                if (evalResultValue != null && evalResultValue.length() > 0)
1190                    evalResultValue += " " + comp.toString();
1191                else
1192                    evalResultValue = comp.toString();
1193            }
1194            return;
1195        }
1196
1197        if (reconstructionDeclarations != null)
1198            reconstructionDeclarations.pushContext();
1199
1200        HashMap localPrefixes = arg.getLocalPrefixes();
1201        if (localPrefixes != null) {
1202            Iterator it = localPrefixes.keySet().iterator();
1203            String JavaDoc prefix = null;
1204            while (it.hasNext()) {
1205                prefix = (String JavaDoc) it.next();
1206                reconstructionDeclarations.declarePrefix(prefix, (String JavaDoc) localPrefixes.get(prefix));
1207            }
1208        }
1209        if (!hasPrefixMapping && localPrefixes != null)
1210            hasPrefixMapping = true;
1211        boolean isSkolemID = false;
1212        boolean isDependID = false;
1213        boolean putPrefixMapping = false;
1214        noReconstructor = true;
1215        skolemIDs = arg.getSkolemIDs();
1216        if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
1217            isSkolemID = true;
1218        ArrayList dependIDs = arg.getDependIDs();
1219        if (dependIDs != null && !dependIDs.isEmpty())
1220            isDependID = true;
1221        boolean loop = arg.getLoop();
1222
1223        XQueryExpression startTag = arg.getStartTag();
1224
1225        // CASE : this element has no skolem ids
1226
if (!isSkolemID) {
1227            // CASE : the element is written until there are no more results available
1228
if (loop) {
1229                // no not continue if dependIDs changed
1230
if (this.noResultSet && dependIDs != lastDependIDs)
1231                    return;
1232                while (true) {
1233                    evalNeeded = true;
1234                    startTag.accept(this);
1235                    evalNeeded = false;
1236                    String JavaDoc nameSpace = evalResultNamespace;
1237                    String JavaDoc localName = evalResultValue;
1238                    evalResultNamespace = null;
1239                    evalResultValue = null;
1240                    if (nameSpace != EMPTY_STRING) {
1241                        String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpace);
1242                        if (prefix == null) {
1243                            if (declaredDeclarations != null)
1244                                prefix = declaredDeclarations.getPrefix(nameSpace);
1245                            if (prefix != null)
1246                                reconstructionDeclarations.declarePrefix(prefix, nameSpace == null ? "" : nameSpace);
1247                        }
1248                    }
1249                    // special for computed namespaces
1250
if (arg.getComputedNSNum() > 0) {
1251                        for (int i = 0; i < arg.getComputedNSNum(); i++) {
1252                            ComputedNamespace compNS = (ComputedNamespace) arg.getSubExpressions().get(i);
1253                            evalNeeded = true;
1254                            compNS.getExpression().accept(this);
1255                            evalNeeded = false;
1256                            reconstructionDeclarations.declarePrefix(compNS.getNcname(), evalResultValue == null ? "" : evalResultValue);
1257                        }
1258                        hasPrefixMapping = true;
1259                    }
1260                    // case of namespace in top element
1261
if (hasPrefixMapping) {
1262                        startPrefixMapping(root);
1263                        hasPrefixMapping = false;
1264                        putPrefixMapping = true;
1265                    }
1266                    // prepare attributes
1267
prepareAttributes(arg);
1268                    // case of attributes (to be evaluated in sons) to add at <start_element>
1269
buildAttributes(arg);
1270                    // WRITE START
1271
startElement(nameSpace, localName, "", listAttributes);
1272                    // WRITE SONS
1273
ArrayList subExpressions = arg.getSubExpressions();
1274                    if (subExpressions != null) {
1275                        boolean previousRoot = root;
1276                        root = false;
1277                        reconstructionHandler.reset(false);
1278                        for (int i = arg.getComputedNSNum() + arg.getComputedAttNum(); i < subExpressions.size(); i++) {
1279                            XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
1280                            expr.accept(this);
1281                            reconstructionHandler.reset(reconstructionHandler.IsOnlyChars());
1282                            this.skolemIDs = arg.getSkolemIDs();
1283                            if (skolemIDs != null)
1284                                lastSkolemIDsSize = skolemIDs.size();
1285                        }
1286                        root = previousRoot;
1287                    }
1288                    // WRITE STOP
1289
endElement(nameSpace, localName, "");
1290                    // case of namespace in top element
1291
if (putPrefixMapping) {
1292                        hasPrefixMapping = true;
1293                        putPrefixMapping = false;
1294                        endPrefixMapping(root);
1295                    }
1296                    noReconstructor = true;
1297                    if (hasNext())
1298                        nextAsSAX();
1299                    else
1300                        break;
1301                }
1302            }
1303            // CASE : no loop and element has depend ids
1304
else if (isDependID) {
1305                noNext = false;
1306                boolean changeDependIDs = true;
1307                /// !!! DANGER !!! THIS is stupid code!!! ( )
1308
try {
1309                    this.setIdentifiers(false);
1310                } catch (XQueryException e) {
1311                    changeDependIDs = false;
1312                }
1313                while (!isEmpty(dependIDs) && changeDependIDs) {
1314                    // case of namespace in top element
1315
evalNeeded = true;
1316                    startTag.accept(this);
1317                    evalNeeded = false;
1318                    String JavaDoc nameSpace = evalResultNamespace;
1319                    String JavaDoc localName = evalResultValue;
1320                    evalResultNamespace = null;
1321                    evalResultValue = null;
1322                    if (nameSpace != EMPTY_STRING) {
1323                        String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpace);
1324                        if (prefix == null) {
1325                            if (declaredDeclarations != null)
1326                                prefix = declaredDeclarations.getPrefix(nameSpace);
1327                            if (prefix != null)
1328                                reconstructionDeclarations.declarePrefix(prefix, nameSpace == null ? "" : nameSpace);
1329                        }
1330                    }
1331                    // special for computed namespaces
1332
if (arg.getComputedNSNum() > 0) {
1333                        for (int i = 0; i < arg.getComputedNSNum(); i++) {
1334                            ComputedNamespace compNS = (ComputedNamespace) arg.getSubExpressions().get(i);
1335                            evalNeeded = true;
1336                            compNS.getExpression().accept(this);
1337                            evalNeeded = false;
1338                            reconstructionDeclarations.declarePrefix(compNS.getNcname(), evalResultValue == null ? "" : evalResultValue);
1339                        }
1340                        hasPrefixMapping = true;
1341                    }
1342                    if (hasPrefixMapping) {
1343                        startPrefixMapping(root);
1344                        hasPrefixMapping = false;
1345                        putPrefixMapping = true;
1346                    }
1347                    // prepare attributes
1348
prepareAttributes(arg);
1349                    // case of attributes (to be evaluated in sons) to add at <start_element>
1350
buildAttributes(arg);
1351                    // WRITE START
1352
startElement(nameSpace, localName, "", listAttributes);
1353                    // set lastSkolemIDsSize
1354
this.skolemIDs = arg.getSkolemIDs();
1355                    if (skolemIDs != null)
1356                        lastSkolemIDsSize = skolemIDs.size();
1357                    // WRITE SONS
1358
ArrayList subExpressions = arg.getSubExpressions();
1359                    if (subExpressions != null) {
1360                        boolean previousRoot = root;
1361                        root = false;
1362                        reconstructionHandler.reset(false);
1363                        for (int i = arg.getComputedAttNum() + arg.getComputedNSNum(); i < subExpressions.size(); i++) {
1364                            XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
1365                            expr.accept(this);
1366                            reconstructionHandler.reset(reconstructionHandler.IsOnlyChars());
1367                            this.skolemIDs = arg.getSkolemIDs();
1368                            if (skolemIDs != null)
1369                                lastSkolemIDsSize = skolemIDs.size();
1370                        }
1371                        root = previousRoot;
1372                    }
1373                    // WRITE STOP
1374
endElement(nameSpace, localName, "");
1375                    // case of namespace in top element
1376
if (putPrefixMapping) {
1377                        hasPrefixMapping = true;
1378                        putPrefixMapping = false;
1379                        endPrefixMapping(root);
1380                    }
1381                    if (!hasNext())
1382                        break;
1383                    changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
1384                    if (!changeDependIDs) {
1385                        noNext = false;
1386                        break;
1387                    } else if (!isEmpty(dependIDs))
1388                        noNext = false;
1389                    if (!noNext) {
1390                        noReconstructor = true;
1391                        if (!hasNext())
1392                            break;
1393                        identifierCopy(currentIdentifiers, lastIdentifiers);
1394                        nextAsSAX();
1395                        this.setIdentifiers(true);
1396                    }
1397                    if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
1398                        noNext = true;
1399                }
1400            } else {
1401                evalNeeded = true;
1402                startTag.accept(this);
1403                evalNeeded = false;
1404                String JavaDoc nameSpace = evalResultNamespace;
1405                String JavaDoc localName = evalResultValue;
1406                evalResultNamespace = null;
1407                evalResultValue = null;
1408                if (nameSpace != EMPTY_STRING) {
1409                    String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpace);
1410                    if (prefix == null) {
1411                        if (declaredDeclarations != null)
1412                            prefix = declaredDeclarations.getPrefix(nameSpace);
1413                        if (prefix != null)
1414                            reconstructionDeclarations.declarePrefix(prefix, nameSpace == null ? "" : nameSpace);
1415                    }
1416                }
1417                // special for computed namespaces
1418
if (arg.getComputedNSNum() > 0) {
1419                    for (int i = 0; i < arg.getComputedNSNum(); i++) {
1420                        ComputedNamespace compNS = (ComputedNamespace) arg.getSubExpressions().get(i);
1421                        evalNeeded = true;
1422                        compNS.getExpression().accept(this);
1423                        evalNeeded = false;
1424                        reconstructionDeclarations.declarePrefix(compNS.getNcname(), evalResultValue == null ? "" : evalResultValue);
1425                    }
1426                    hasPrefixMapping = true;
1427                }
1428                // case of namespace in top element
1429
if (hasPrefixMapping) {
1430                    startPrefixMapping(root);
1431                    hasPrefixMapping = false;
1432                    putPrefixMapping = true;
1433                }
1434                // prepare attributes
1435
prepareAttributes(arg);
1436                // case of attributes (to be evaluated in sons) to add at <start_element>
1437
buildAttributes(arg);
1438                // WRITE START
1439
startElement(nameSpace, localName, "", listAttributes);
1440                // WRITE SONS
1441
ArrayList subExpressions = arg.getSubExpressions();
1442                if (subExpressions != null) {
1443                    boolean previousRoot = root;
1444                    root = false;
1445                    reconstructionHandler.reset(false);
1446                    for (int i = arg.getComputedAttNum() + arg.getComputedNSNum(); i < subExpressions.size(); i++) {
1447                        XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
1448                        expr.accept(this);
1449                        reconstructionHandler.reset(reconstructionHandler.IsOnlyChars());
1450                        this.skolemIDs = arg.getSkolemIDs();
1451                    }
1452                    root = previousRoot;
1453                }
1454                // WRITE STOP
1455
endElement(nameSpace, localName, "");
1456                // case of namespace in top element
1457
if (putPrefixMapping) {
1458                    hasPrefixMapping = true;
1459                    putPrefixMapping = false;
1460                    endPrefixMapping(root);
1461                }
1462            }
1463        }
1464        // there is at least a skolemID
1465
else {
1466            // set the current identifier and the next
1467
if (isSkolemID && !arg.getRoot()) {
1468                this.setIdentifiers(false);
1469            }
1470            // there is no dependID
1471
if (dependIDs == null && !arg.getRoot()) {
1472                // CODE NOT USED !!! AS FAR AS I CAN TELL
1473
if (loop) {
1474                    while (true) {
1475                        evalNeeded = true;
1476                        startTag.accept(this);
1477                        evalNeeded = false;
1478                        String JavaDoc nameSpace = evalResultNamespace;
1479                        String JavaDoc localName = evalResultValue;
1480                        evalResultNamespace = null;
1481                        evalResultValue = null;
1482                        if (nameSpace != EMPTY_STRING) {
1483                            String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpace);
1484                            if (prefix == null) {
1485                                if (declaredDeclarations != null)
1486                                    prefix = declaredDeclarations.getPrefix(nameSpace);
1487                                if (prefix != null)
1488                                    reconstructionDeclarations.declarePrefix(prefix, nameSpace == null ? "" : nameSpace);
1489                            }
1490                        }
1491                        // special for computed namespaces
1492
if (arg.getComputedNSNum() > 0) {
1493                            for (int i = 0; i < arg.getComputedNSNum(); i++) {
1494                                ComputedNamespace compNS = (ComputedNamespace) arg.getSubExpressions().get(i);
1495                                evalNeeded = true;
1496                                compNS.getExpression().accept(this);
1497                                evalNeeded = false;
1498                                reconstructionDeclarations.declarePrefix(compNS.getNcname(), evalResultValue == null ? "" : evalResultValue);
1499                            }
1500                            hasPrefixMapping = true;
1501                        }
1502                        // case of namespace in top element
1503
if (hasPrefixMapping) {
1504                            startPrefixMapping(root);
1505                            hasPrefixMapping = false;
1506                            putPrefixMapping = true;
1507                        }
1508                        // prepare attributes
1509
prepareAttributes(arg);
1510                        // case of attributes (to be evaluated in sons) to add at <start_element>
1511
buildAttributes(arg);
1512                        // WRITE START
1513
startElement(nameSpace, localName, "", listAttributes);
1514                        // set lastSkolemIDsSize
1515
this.skolemIDs = arg.getSkolemIDs();
1516                        if (skolemIDs != null)
1517                            lastSkolemIDsSize = skolemIDs.size();
1518                        // WRITE SONS
1519
ArrayList subExpressions = arg.getSubExpressions();
1520                        if (subExpressions != null) {
1521                            boolean previousRoot = root;
1522                            root = false;
1523                            reconstructionHandler.reset(false);
1524                            for (int i = arg.getComputedAttNum() + arg.getComputedNSNum(); i < subExpressions.size(); i++) {
1525                                XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
1526                                expr.accept(this);
1527                                reconstructionHandler.reset(reconstructionHandler.IsOnlyChars());
1528                                this.skolemIDs = arg.getSkolemIDs();
1529                                if (skolemIDs != null)
1530                                    lastSkolemIDsSize = skolemIDs.size();
1531                            }
1532                            root = previousRoot;
1533                        }
1534
1535                        // WRITE STOP
1536
endElement(nameSpace, localName, "");
1537                        // case of namespace in top element
1538
if (putPrefixMapping) {
1539                            hasPrefixMapping = true;
1540                            putPrefixMapping = false;
1541                            endPrefixMapping(root);
1542                        }
1543                        noReconstructor = true;
1544                        noNext = false;
1545                        if (hasNext())
1546                            nextAsSAX();
1547                        else
1548                            break;
1549                    }
1550                } else {
1551                    evalNeeded = true;
1552                    startTag.accept(this);
1553                    evalNeeded = false;
1554                    String JavaDoc nameSpace = evalResultNamespace;
1555                    String JavaDoc localName = evalResultValue;
1556                    evalResultNamespace = null;
1557                    evalResultValue = null;
1558                    if (nameSpace != EMPTY_STRING) {
1559                        String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpace);
1560                        if (prefix == null) {
1561                            if (declaredDeclarations != null)
1562                                prefix = declaredDeclarations.getPrefix(nameSpace);
1563                            if (prefix != null)
1564                                reconstructionDeclarations.declarePrefix(prefix, nameSpace == null ? "" : nameSpace);
1565                        }
1566                    }
1567                    // special for computed namespaces
1568
if (arg.getComputedNSNum() > 0) {
1569                        for (int i = 0; i < arg.getComputedNSNum(); i++) {
1570                            ComputedNamespace compNS = (ComputedNamespace) arg.getSubExpressions().get(i);
1571                            evalNeeded = true;
1572                            compNS.getExpression().accept(this);
1573                            evalNeeded = false;
1574                            reconstructionDeclarations.declarePrefix(compNS.getNcname(), evalResultValue == null ? "" : evalResultValue);
1575                        }
1576                        hasPrefixMapping = true;
1577                    }
1578                    // case of namespace in top element
1579
if (hasPrefixMapping) {
1580                        startPrefixMapping(root);
1581                        hasPrefixMapping = false;
1582                        putPrefixMapping = true;
1583                    }
1584                    // prepare attributes
1585
prepareAttributes(arg);
1586                    // case of attributes (to be evaluated in sons) to add at <start_element>
1587
buildAttributes(arg);
1588                    // WRITE START
1589
startElement(nameSpace, localName, "", listAttributes);
1590                    // set lastSkolemIDsSize
1591
this.skolemIDs = arg.getSkolemIDs();
1592                    if (skolemIDs != null)
1593                        lastSkolemIDsSize = skolemIDs.size();
1594                    // WRITE SONS
1595
ArrayList subExpressions = arg.getSubExpressions();
1596                    if (subExpressions != null) {
1597                        boolean previousRoot = root;
1598                        root = false;
1599                        reconstructionHandler.reset(false);
1600                        for (int i = arg.getComputedAttNum() + arg.getComputedNSNum(); i < subExpressions.size(); i++) {
1601                            XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
1602                            expr.accept(this);
1603                            reconstructionHandler.reset(reconstructionHandler.IsOnlyChars());
1604                            this.skolemIDs = arg.getSkolemIDs();
1605                            if (skolemIDs != null)
1606                                lastSkolemIDsSize = skolemIDs.size();
1607                        }
1608                        root = previousRoot;
1609                    }
1610                    // WRITE STOP
1611
endElement(nameSpace, localName, "");
1612                    // case of namespace in top element
1613
if (putPrefixMapping) {
1614                        hasPrefixMapping = true;
1615                        putPrefixMapping = false;
1616                        endPrefixMapping(root);
1617                    }
1618                }
1619            } else // dependIDs != null or arg element is root
1620
{
1621                noNext = false;
1622                if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
1623                    boolean changeDependIDs = true;
1624
1625                    boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
1626                    // stop if the skolemIDs changed, and that dependIDs does not have an incidence
1627
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
1628                        if (reconstructionDeclarations != null)
1629                            reconstructionDeclarations.popContext();
1630                        return;
1631                    }
1632
1633                    int firstDependIDPosition = 0;
1634                    if (dependIDs != null && !dependIDs.isEmpty()) {
1635                        firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
1636                    }
1637                    int skipEntries = -1;
1638                    if (firstDependIDPosition > skolemIDs.size()) {
1639                        skipEntries = lastSkolemIDsSize;
1640                        while (!changeSkolemIDs && isEmpty(dependIDs)) {
1641                            if (!hasNext())
1642                                break;
1643                            identifierCopy(currentIdentifiers, lastIdentifiers);
1644                            nextAsSAX();
1645                            this.setIdentifiers(true);
1646                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
1647                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
1648                        }
1649                    }
1650                    while (!isEmpty(dependIDs) && changeDependIDs) {
1651                        evalNeeded = true;
1652                        startTag.accept(this);
1653                        evalNeeded = false;
1654                        String JavaDoc nameSpace = evalResultNamespace;
1655                        String JavaDoc localName = evalResultValue;
1656                        evalResultNamespace = null;
1657                        evalResultValue = null;
1658                        if (nameSpace != EMPTY_STRING) {
1659                            String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpace);
1660                            if (prefix == null) {
1661                                if (declaredDeclarations != null)
1662                                    prefix = declaredDeclarations.getPrefix(nameSpace);
1663                                if (prefix != null)
1664                                    reconstructionDeclarations.declarePrefix(prefix, nameSpace == null ? "" : nameSpace);
1665                            }
1666                        }
1667                        // special for computed namespaces
1668
if (arg.getComputedNSNum() > 0) {
1669                            for (int i = 0; i < arg.getComputedNSNum(); i++) {
1670                                ComputedNamespace compNS = (ComputedNamespace) arg.getSubExpressions().get(i);
1671                                evalNeeded = true;
1672                                compNS.getExpression().accept(this);
1673                                evalNeeded = false;
1674                                reconstructionDeclarations.declarePrefix(compNS.getNcname(), evalResultValue == null ? "" : evalResultValue);
1675                            }
1676                            hasPrefixMapping = true;
1677                        }
1678                        // case of namespace in top element
1679
if (hasPrefixMapping) {
1680                            startPrefixMapping(root);
1681                            hasPrefixMapping = false;
1682                            putPrefixMapping = true;
1683                        }
1684                        // prepare attributes
1685
prepareAttributes(arg);
1686                        // case of attributes (to be evaluated in sons) to add at <start_element>
1687
buildAttributes(arg);
1688                        // WRITE START
1689
startElement(nameSpace, localName, "", listAttributes);
1690                        // set lastSkolemIDsSize
1691
this.skolemIDs = arg.getSkolemIDs();
1692                        if (skolemIDs != null)
1693                            lastSkolemIDsSize = skolemIDs.size();
1694                        // WRITE SONS
1695
ArrayList subExpressions = arg.getSubExpressions();
1696                        if (subExpressions != null) {
1697                            boolean previousRoot = root;
1698                            root = false;
1699                            reconstructionHandler.reset(false);
1700                            for (int i = arg.getComputedAttNum() + arg.getComputedNSNum(); i < subExpressions.size(); i++) {
1701                                XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
1702                                expr.accept(this);
1703                                reconstructionHandler.reset(reconstructionHandler.IsOnlyChars());
1704                                this.skolemIDs = arg.getSkolemIDs();
1705                                if (skolemIDs != null)
1706                                    lastSkolemIDsSize = skolemIDs.size();
1707                            }
1708                            root = previousRoot;
1709                        }
1710                        // WRITE STOP
1711
endElement(nameSpace, localName, "");
1712                        // case of namespace in top element
1713
if (putPrefixMapping) {
1714                            hasPrefixMapping = true;
1715                            putPrefixMapping = false;
1716                            endPrefixMapping(root);
1717                        }
1718                        if (!hasNext())
1719                            break;
1720                        if (skipEntries == -1) {
1721                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
1722                            if (!changeDependIDs) {
1723                                noNext = false;
1724                                break;
1725                            } else if (!isEmpty(dependIDs))
1726                                noNext = false;
1727                        }
1728                        // ----------------------------
1729
// ADDED
1730
//-----------------------------
1731
else {
1732                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
1733                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
1734                            if (!changeSkolemIDs) {
1735                                noNext = false;
1736                                boolean noDependIDs = true;
1737                                boolean makeBreak = false;
1738                                noReInit = false;
1739                                while (!changeSkolemIDs && noDependIDs) {
1740                                    noReconstructor = true;
1741                                    if (!hasNext()) {
1742                                        makeBreak = true;
1743                                        break;
1744                                    }
1745                                    identifierCopy(currentIdentifiers, lastIdentifiers);
1746                                    nextAsSAX();
1747                                    this.setIdentifiers(true);
1748                                    changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
1749                                    noDependIDs = isEmpty(dependIDs);
1750                                }
1751                                if (makeBreak)
1752                                    break;
1753                                noNext = true;
1754                                if (!noDependIDs)
1755                                    noReInit = true;
1756                                changeDependIDs = true;
1757                            } else if (!isEmpty(dependIDs))
1758                                noNext = false;
1759                        }
1760                        // ----------------------------
1761
// END ADDED
1762
//-----------------------------
1763
if (!noNext && !changeSkolemIDs) {
1764                            noReconstructor = true;
1765                            if (!hasNext())
1766                                break;
1767                            identifierCopy(currentIdentifiers, lastIdentifiers);
1768                            nextAsSAX();
1769                            this.setIdentifiers(true);
1770                        }
1771                        if (skipEntries == -1) {
1772                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
1773                                noNext = true;
1774                        } else {
1775                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
1776                                noNext = false; // CHANGE 03/07/2002 was initially true
1777
}
1778                    }
1779                } else {
1780                    boolean changeSkolemIDs = false;
1781                    while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
1782                        evalNeeded = true;
1783                        startTag.accept(this);
1784                        evalNeeded = false;
1785                        String JavaDoc nameSpace = evalResultNamespace;
1786                        String JavaDoc localName = evalResultValue;
1787                        evalResultNamespace = null;
1788                        evalResultValue = null;
1789                        if (nameSpace != EMPTY_STRING) {
1790                            String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpace);
1791                            if (prefix == null) {
1792                                if (declaredDeclarations != null)
1793                                    prefix = declaredDeclarations.getPrefix(nameSpace);
1794                                if (prefix != null)
1795                                    reconstructionDeclarations.declarePrefix(prefix, nameSpace == null ? "" : nameSpace);
1796                            }
1797                        }
1798                        // special for computed namespaces
1799
if (arg.getComputedNSNum() > 0) {
1800                            for (int i = 0; i < arg.getComputedNSNum(); i++) {
1801                                ComputedNamespace compNS = (ComputedNamespace) arg.getSubExpressions().get(i);
1802                                evalNeeded = true;
1803                                compNS.getExpression().accept(this);
1804                                evalNeeded = false;
1805                                reconstructionDeclarations.declarePrefix(compNS.getNcname(), evalResultValue == null ? "" : evalResultValue);
1806                            }
1807                            hasPrefixMapping = true;
1808                        }
1809                        // case of namespace in top element
1810
if (hasPrefixMapping) {
1811                            startPrefixMapping(root);
1812                            hasPrefixMapping = false;
1813                            putPrefixMapping = true;
1814                        }
1815                        // prepare attributes
1816
prepareAttributes(arg);
1817                        // case of attributes (to be evaluated in sons) to add at <start_element>
1818
buildAttributes(arg);
1819                        startElement(nameSpace, localName, "", listAttributes);
1820                        // set lastSkolemIDsSize
1821
this.skolemIDs = arg.getSkolemIDs();
1822                        if (skolemIDs != null)
1823                            lastSkolemIDsSize = skolemIDs.size();
1824                        // set last dependIDs
1825
lastDependIDs = dependIDs;
1826                        // WRITE SONS
1827
ArrayList subExpressions = arg.getSubExpressions();
1828                        if (subExpressions != null) {
1829                            boolean previousRoot = root;
1830                            root = false;
1831                            byte num = 0;
1832                            for (int i = arg.getComputedAttNum() + arg.getComputedNSNum(); i < subExpressions.size(); i++) {
1833                                if (!((XQueryExpression) subExpressions.get(i) instanceof Value))
1834                                    num++;
1835                                if (num > 1)
1836                                    break;
1837                            }
1838                            reconstructionHandler.reset(false);
1839                            for (int i = arg.getComputedAttNum() + arg.getComputedNSNum(); i < subExpressions.size(); i++) {
1840                                XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
1841                                // CHANGED 10/04/2003
1842
if (num == 1 && arg.getRoot())
1843                                    expr.setRoot(true);
1844                                expr.accept(this);
1845                                reconstructionHandler.reset(reconstructionHandler.IsOnlyChars());
1846                                this.skolemIDs = arg.getSkolemIDs();
1847                                if (skolemIDs != null)
1848                                    lastSkolemIDsSize = skolemIDs.size();
1849                            }
1850                            root = previousRoot;
1851                        }
1852                        // WRITE STOP
1853
endElement(nameSpace, localName, "");
1854                        // case of namespace in top element
1855
if (putPrefixMapping) {
1856                            hasPrefixMapping = true;
1857                            putPrefixMapping = false;
1858                            endPrefixMapping(root);
1859                        }
1860                        if (!hasNext())
1861                            break;
1862                        if (!arg.getRoot())
1863                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
1864                        if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
1865                            noReconstructor = true;
1866                            if (!hasNext())
1867                                break;
1868                            identifierCopy(currentIdentifiers, lastIdentifiers);
1869                            nextAsSAX();
1870                            this.setIdentifiers(true);
1871                        }
1872                        if (changeSkolemIDs)
1873                            noNext = true;
1874                        if (arg.getRoot())
1875                            break;
1876                    }
1877                    // while (!changeSkolemIDs);
1878
}
1879                // noNext = true;
1880
}
1881        }
1882        if (reconstructionDeclarations != null)
1883            reconstructionDeclarations.popContext();
1884        noReconstructor = false;
1885    }
1886
1887    // public void visit(ExternalVariable arg) throws XQueryException {
1888

1889    private void outputITEExpression(ITEExpression arg) throws XQueryException {
1890        evalVisitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE);
1891        arg.getIfExpression().accept(evalVisitor);
1892        if (evalVisitor.getVerdict())
1893            arg.getThenExpression().accept(this);
1894        else
1895            arg.getElseExpression().accept(this);
1896        // reset key variables
1897
skolemIDs = arg.getSkolemIDs();
1898        if (skolemIDs != null)
1899            lastSkolemIDsSize = skolemIDs.size();
1900    }
1901
1902    public void visit(ITEExpression arg) throws XQueryException { // TODO !!!!! nearly the SAME as Element
1903

1904        boolean isSkolemID = false;
1905        boolean isDependID = false;
1906        noReconstructor = true;
1907        skolemIDs = arg.getSkolemIDs();
1908        if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
1909            isSkolemID = true;
1910        ArrayList dependIDs = arg.getDependIDs();
1911        if (dependIDs != null && !dependIDs.isEmpty())
1912            isDependID = true;
1913        boolean loop = arg.getLoop();
1914
1915        // CASE : this element has no skolem ids
1916
if (!isSkolemID) {
1917            // CASE : the element is written until there are no more results available
1918
if (loop) {
1919                // no not continue if dependIDs changed
1920
if (this.noResultSet && dependIDs != lastDependIDs)
1921                    return;
1922                while (true) {
1923                    outputITEExpression(arg);
1924                    noReconstructor = true;
1925                    if (hasNext())
1926                        nextAsSAX();
1927                    else
1928                        break;
1929                }
1930            }
1931            // CASE : no loop and element has depend ids
1932
else if (isDependID) {
1933                noNext = false;
1934                boolean changeDependIDs = true;
1935                /// !!! DANGER !!! THIS is stupid code!!! ( )
1936
try {
1937                    this.setIdentifiers(false);
1938                } catch (XQueryException e) {
1939                    changeDependIDs = false;
1940                }
1941                while (!isEmpty(dependIDs) && changeDependIDs) {
1942                    // case of namespace in top element
1943
outputITEExpression(arg);
1944                    if (!hasNext())
1945                        break;
1946                    changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
1947                    if (!changeDependIDs) {
1948                        noNext = false;
1949                        break;
1950                    } else if (!isEmpty(dependIDs))
1951                        noNext = false;
1952                    if (!noNext) {
1953                        noReconstructor = true;
1954                        if (!hasNext())
1955                            break;
1956                        identifierCopy(currentIdentifiers, lastIdentifiers);
1957                        nextAsSAX();
1958                        this.setIdentifiers(true);
1959                    }
1960                    if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
1961                        noNext = true;
1962                }
1963            } else {
1964                outputITEExpression(arg);
1965            }
1966        }
1967        // there is at least a skolemID
1968
else {
1969
1970            // set the current identifier and the next
1971
if (isSkolemID && !arg.getRoot()) {
1972                this.setIdentifiers(false);
1973            }
1974            // there is no dependID
1975
if (dependIDs == null && !arg.getRoot()) {
1976                // CODE NOT USED !!! AS FAR AS I CAN TELL
1977
if (loop) {
1978                    while (true) {
1979                        outputITEExpression(arg);
1980                        // WRITE STOP
1981
noReconstructor = true;
1982                        noNext = false;
1983                        if (hasNext())
1984                            nextAsSAX();
1985                        else
1986                            break;
1987                    }
1988                } else {
1989                    outputITEExpression(arg);
1990                }
1991            } else // dependIDs != null or arg element is root
1992
{
1993                noNext = false;
1994                if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
1995                    boolean changeDependIDs = true;
1996
1997                    boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
1998                    // stop if the skolemIDs changed, and that dependIDs does not have an incidence
1999
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
2000                        return;
2001                    }
2002
2003                    int firstDependIDPosition = 0;
2004                    if (dependIDs != null && !dependIDs.isEmpty()) {
2005                        firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
2006                    }
2007                    int skipEntries = -1;
2008                    if (firstDependIDPosition > skolemIDs.size()) {
2009                        skipEntries = lastSkolemIDsSize;
2010                        while (!changeSkolemIDs && isEmpty(dependIDs)) {
2011                            if (!hasNext())
2012                                break;
2013                            identifierCopy(currentIdentifiers, lastIdentifiers);
2014                            nextAsSAX();
2015                            this.setIdentifiers(true);
2016                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
2017                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
2018                        }
2019                    }
2020                    while (!isEmpty(dependIDs) && changeDependIDs) {
2021                        outputITEExpression(arg);
2022                        if (!hasNext())
2023                            break;
2024                        if (skipEntries == -1) {
2025                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
2026                            if (!changeDependIDs) {
2027                                noNext = false;
2028                                break;
2029                            } else if (!isEmpty(dependIDs))
2030                                noNext = false;
2031                        }
2032                        // ----------------------------
2033
// ADDED
2034
//-----------------------------
2035
else {
2036                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
2037                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
2038                            if (!changeSkolemIDs) {
2039                                noNext = false;
2040                                boolean noDependIDs = true;
2041                                boolean makeBreak = false;
2042                                noReInit = false;
2043                                while (!changeSkolemIDs && noDependIDs) {
2044                                    noReconstructor = true;
2045                                    if (!hasNext()) {
2046                                        makeBreak = true;
2047                                        break;
2048                                    }
2049                                    identifierCopy(currentIdentifiers, lastIdentifiers);
2050                                    nextAsSAX();
2051                                    this.setIdentifiers(true);
2052                                    changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
2053                                    noDependIDs = isEmpty(dependIDs);
2054                                }
2055                                if (makeBreak)
2056                                    break;
2057                                noNext = true;
2058                                if (!noDependIDs)
2059                                    noReInit = true;
2060                                changeDependIDs = true;
2061                            } else if (!isEmpty(dependIDs))
2062                                noNext = false;
2063                        }
2064                        // ----------------------------
2065
// END ADDED
2066
//-----------------------------
2067
if (!noNext && !changeSkolemIDs) {
2068                            noReconstructor = true;
2069                            if (!hasNext())
2070                                break;
2071                            identifierCopy(currentIdentifiers, lastIdentifiers);
2072                            nextAsSAX();
2073                            this.setIdentifiers(true);
2074                        }
2075                        if (skipEntries == -1) {
2076                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
2077                                noNext = true;
2078                        } else {
2079                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
2080                                noNext = false; // CHANGE 03/07/2002 was initially true
2081
}
2082                    }
2083                } else {
2084                    boolean changeSkolemIDs = false;
2085                    while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
2086                        // set last dependIDs
2087
lastDependIDs = dependIDs;
2088                        outputITEExpression(arg);
2089                        if (!hasNext())
2090                            break;
2091
2092                        if (!arg.getRoot())
2093                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
2094                        if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
2095                            noReconstructor = true;
2096                            if (!hasNext())
2097                                break;
2098                            identifierCopy(currentIdentifiers, lastIdentifiers);
2099                            nextAsSAX();
2100                            this.setIdentifiers(true);
2101                        }
2102                        if (changeSkolemIDs)
2103                            noNext = true;
2104                        if (arg.getRoot())
2105                            break;
2106                    }
2107                    // while (!changeSkolemIDs);
2108
}
2109                // noNext = true;
2110
}
2111        }
2112        noReconstructor = false;
2113
2114    }
2115
2116    public void visit(LibraryFunctionCall arg) throws XQueryException {
2117        evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
2118        arg.accept(evalVisitor);
2119        Comparable JavaDoc comp = evalVisitor.getResValue();
2120        characters(comp.toString().toCharArray(), 0, comp.toString().length());
2121    }
2122
2123    public void visit(XQueryVoid arg) throws XQueryException {
2124        // do nothing
2125
}
2126
2127    private void outputLocatedExpression(LocatedExpression arg, int nodeAccessor) throws XQueryException {
2128        if (!noResultSet) {
2129            generate(arg.getStringValue(), nodeAccessor, arg.getLoopIDs());
2130        }
2131    }
2132
2133    public void visit(LocatedExpression arg) throws XQueryException { // TODO !!!!! nearly the SAME as Element
2134

2135        if (evalNeeded) {
2136            evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
2137            arg.accept(evalVisitor);
2138            evalResultNamespace = EMPTY_STRING;
2139            Comparable JavaDoc comp = evalVisitor.getResValue();
2140            if (comp == null)
2141                evalResultValue = EMPTY_STRING;
2142            else {
2143                if (evalResultValue != null && evalResultValue.length() > 0)
2144                    evalResultValue += " " + comp.toString();
2145                else
2146                    evalResultValue = comp.toString();
2147            }
2148            return;
2149        }
2150
2151        boolean putPrefixMapping = false;
2152
2153        if (hasPrefixMapping) {
2154            startPrefixMapping(true);
2155            hasPrefixMapping = false;
2156            putPrefixMapping = true;
2157        }
2158
2159        ArrayList steps = arg.getSteps();
2160        int nodeAccessor = arg.getNodeAccessor();
2161        boolean hasSpecialStep = false;
2162        if (nodeAccessor == Step.NONE) {
2163            int lastPosition = steps.size() - 1;
2164            Step lastStep = (Step) steps.get(lastPosition);
2165            if (lastStep.getStepKind() % 16 != 0) {
2166                arg.setNodeAccessor(lastStep.getStepKind());
2167                nodeAccessor = arg.getNodeAccessor();
2168                steps.remove(lastPosition);
2169            }
2170            // XQueryExpression lastStepExpr = lastStep.getExpression();
2171
// if (lastStepExpr instanceof NodeTest) {
2172
// switch (((NodeTest) lastStepExpr).getKind()) {
2173
// case NodeKind.NODE :
2174
// if (lastStep.getAxis() == Axis.CHILD) {
2175
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_NODE;
2176
// steps.remove(lastPosition);
2177
// hasSpecialStep = true;
2178
// } else if (lastStep.getAxis() == Axis.SELF) {
2179
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_SELF_NODE;
2180
// steps.remove(lastPosition);
2181
// hasSpecialStep = true;
2182
// }
2183
// break;
2184
// case NodeKind.TEXT :
2185
// if (lastStep.getAxis() == Axis.CHILD) {
2186
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_TEXT;
2187
// steps.remove(lastPosition);
2188
// hasSpecialStep = true;
2189
// } else if (lastStep.getAxis() == Axis.SELF) {
2190
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_SELF_TEXT;
2191
// steps.remove(lastPosition);
2192
// hasSpecialStep = true;
2193
// }
2194
// break;
2195
// }
2196
// }
2197
}
2198        boolean isSkolemID = false;
2199        boolean isDependID = false;
2200        noReconstructor = true;
2201        if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
2202            isSkolemID = true;
2203        ArrayList dependIDs = arg.getDependIDs();
2204        if (dependIDs != null && !dependIDs.isEmpty())
2205            isDependID = true;
2206        boolean loop = arg.getLoop();
2207
2208        // CASE : this element has no skolem ids
2209
if (!isSkolemID) {
2210            // CASE : the element is written until there are no more results available
2211
if (loop) {
2212                // no not continue if dependIDs changed
2213
if (this.noResultSet && dependIDs != lastDependIDs)
2214                    return;
2215                while (true) {
2216                    outputLocatedExpression(arg, nodeAccessor);
2217                    noReconstructor = true;
2218                    if (hasNext())
2219                        nextAsSAX();
2220                    else
2221                        break;
2222                }
2223            }
2224            // CASE : no loop and element has depend ids
2225
else if (isDependID) {
2226                noNext = false;
2227                boolean changeDependIDs = true;
2228                /// !!! DANGER !!! THIS is stupid code!!! ( )
2229
try {
2230                    this.setIdentifiers(false);
2231                } catch (XQueryException e) {
2232                    changeDependIDs = false;
2233                }
2234                while (!isEmpty(dependIDs) && changeDependIDs) {
2235                    // case of namespace in top element
2236
// set lastSkolemIDsSize
2237
if (skolemIDs != null)
2238                        lastSkolemIDsSize = skolemIDs.size();
2239                    outputLocatedExpression(arg, nodeAccessor);
2240                    if (!hasNext())
2241                        break;
2242                    changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
2243                    if (!changeDependIDs) {
2244                        noNext = false;
2245                        break;
2246                    } else if (!isEmpty(dependIDs))
2247                        noNext = false;
2248                    if (!noNext) {
2249                        noReconstructor = true;
2250                        if (!hasNext())
2251                            break;
2252                        identifierCopy(currentIdentifiers, lastIdentifiers);
2253                        nextAsSAX();
2254                        this.setIdentifiers(true);
2255                    }
2256                    if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
2257                        noNext = true;
2258                }
2259            } else {
2260                // WRITE SONS
2261
outputLocatedExpression(arg, nodeAccessor);
2262            }
2263        }
2264        // there is at least a skolemID
2265
else {
2266
2267            // set the current identifier and the next
2268
if (isSkolemID && !arg.getRoot()) {
2269                this.setIdentifiers(false);
2270            }
2271            // there is no dependID
2272
if (dependIDs == null && !arg.getRoot()) {
2273                // CODE NOT USED !!! AS FAR AS I CAN TELL
2274
if (loop) {
2275                    while (true) {
2276                        // set lastSkolemIDsSize
2277
if (skolemIDs != null)
2278                            lastSkolemIDsSize = skolemIDs.size();
2279                        outputLocatedExpression(arg, nodeAccessor);
2280                        // WRITE STOP
2281
noReconstructor = true;
2282                        noNext = false;
2283                        if (hasNext())
2284                            nextAsSAX();
2285                        else
2286                            break;
2287                    }
2288                } else {
2289                    // set lastSkolemIDsSize
2290
if (skolemIDs != null)
2291                        lastSkolemIDsSize = skolemIDs.size();
2292                    // WRITE SONS
2293
outputLocatedExpression(arg, nodeAccessor);
2294                }
2295            } else // dependIDs != null or arg element is root
2296
{
2297                noNext = false;
2298                if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
2299                    boolean changeDependIDs = true;
2300
2301                    boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
2302                    // stop if the skolemIDs changed, and that dependIDs does not have an incidence
2303
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
2304                        return;
2305                    }
2306
2307                    int firstDependIDPosition = 0;
2308                    if (dependIDs != null && !dependIDs.isEmpty()) {
2309                        firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
2310                    }
2311                    int skipEntries = -1;
2312                    if (firstDependIDPosition > skolemIDs.size()) {
2313                        skipEntries = lastSkolemIDsSize;
2314                        while (!changeSkolemIDs && isEmpty(dependIDs)) {
2315                            if (!hasNext())
2316                                break;
2317                            identifierCopy(currentIdentifiers, lastIdentifiers);
2318                            nextAsSAX();
2319                            this.setIdentifiers(true);
2320                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
2321                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
2322                        }
2323                    }
2324                    while (!isEmpty(dependIDs) && changeDependIDs) {
2325                        // set lastSkolemIDsSize
2326
if (skolemIDs != null)
2327                            lastSkolemIDsSize = skolemIDs.size();
2328                        outputLocatedExpression(arg, nodeAccessor);
2329                        if (!hasNext())
2330                            break;
2331                        if (skipEntries == -1) {
2332                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
2333                            if (!changeDependIDs) {
2334                                noNext = false;
2335                                break;
2336                            } else if (!isEmpty(dependIDs))
2337                                noNext = false;
2338                        }
2339                        // ----------------------------
2340
// ADDED
2341
//-----------------------------
2342
else {
2343                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
2344                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
2345                            if (!changeSkolemIDs) {
2346                                noNext = false;
2347                                boolean noDependIDs = true;
2348                                boolean makeBreak = false;
2349                                noReInit = false;
2350                                while (!changeSkolemIDs && noDependIDs) {
2351                                    noReconstructor = true;
2352                                    if (!hasNext()) {
2353                                        makeBreak = true;
2354                                        break;
2355                                    }
2356                                    identifierCopy(currentIdentifiers, lastIdentifiers);
2357                                    nextAsSAX();
2358                                    this.setIdentifiers(true);
2359                                    changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
2360                                    noDependIDs = isEmpty(dependIDs);
2361                                }
2362                                if (makeBreak)
2363                                    break;
2364                                noNext = true;
2365                                if (!noDependIDs)
2366                                    noReInit = true;
2367                                changeDependIDs = true;
2368                            } else if (!isEmpty(dependIDs))
2369                                noNext = false;
2370                        }
2371                        // ----------------------------
2372
// END ADDED
2373
//-----------------------------
2374
if (!noNext && !changeSkolemIDs) {
2375                            noReconstructor = true;
2376                            if (!hasNext())
2377                                break;
2378                            identifierCopy(currentIdentifiers, lastIdentifiers);
2379                            nextAsSAX();
2380                            this.setIdentifiers(true);
2381                        }
2382                        if (skipEntries == -1) {
2383                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
2384                                noNext = true;
2385                        } else {
2386                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
2387                                noNext = false; // CHANGE 03/07/2002 was initially true
2388
}
2389                    }
2390                } else {
2391                    boolean changeSkolemIDs = false;
2392                    while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
2393                        // set lastSkolemIDsSize
2394
if (skolemIDs != null)
2395                            lastSkolemIDsSize = skolemIDs.size();
2396                        // set last dependIDs
2397
lastDependIDs = dependIDs;
2398                        outputLocatedExpression(arg, nodeAccessor);
2399                        if (!hasNext())
2400                            break;
2401
2402                        if (!arg.getRoot())
2403                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
2404                        if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
2405                            noReconstructor = true;
2406                            if (!hasNext())
2407                                break;
2408                            identifierCopy(currentIdentifiers, lastIdentifiers);
2409                            nextAsSAX();
2410                            this.setIdentifiers(true);
2411                        }
2412                        if (changeSkolemIDs)
2413                            noNext = true;
2414                        if (arg.getRoot())
2415                            break;
2416                    }
2417                    // while (!changeSkolemIDs);
2418
}
2419                // noNext = true;
2420
}
2421        }
2422
2423        // if (hasSpecialStep) {
2424
// steps.add(stepText);
2425
// }
2426

2427        noReconstructor = false;
2428        if (putPrefixMapping) {
2429            hasPrefixMapping = true;
2430            putPrefixMapping = false;
2431            endPrefixMapping(true);
2432        }
2433    }
2434
2435    public void visit(QName arg) throws XQueryException {
2436        if (evalNeeded) {
2437            evalResultNamespace = (arg.getNameSpace() == null) ? EMPTY_STRING : arg.getNameSpace();
2438            evalResultValue = (arg.getLocalName() == null) ? EMPTY_STRING : arg.getLocalName();
2439        }
2440    }
2441
2442    //-----------------------------------------------------------
2443
// QNAME FUNCTIONS
2444
//-----------------------------------------------------------
2445

2446    public void visit(FunctionEXPANDED_QNAME arg) throws XQueryException {
2447        if (evalNeeded) {
2448            arg.getArgument(0).accept(this);
2449            String JavaDoc prefix = evalResultValue;
2450            if (prefix == null)
2451                throw new XQueryException("Could not evaluate " + arg.getArgument(0));
2452            String JavaDoc namespace = reconstructionDeclarations.getNamespaceURI(prefix);
2453            if (namespace == null)
2454                throw new XQueryException("Could not find prefix : " + prefix);
2455            arg.getArgument(1).accept(this);
2456            String JavaDoc localname = evalResultValue;
2457            if (localname == null)
2458                throw new XQueryException("Could not evaluate " + arg.getArgument(1));
2459            evalResultNamespace = (namespace == null) ? EMPTY_STRING : namespace;
2460            evalResultValue = (localname == null) ? EMPTY_STRING : localname;
2461        }
2462    }
2463
2464    public void visit(FunctionQNAME arg) throws XQueryException {
2465        if (evalNeeded) {
2466            arg.getArgument(0).accept(this);
2467            String JavaDoc qname = evalResultValue;
2468            if (qname == null)
2469                throw new XQueryException("Could not evaluate " + arg.getArgument(0));
2470            int index = -1;
2471            String JavaDoc namespace = null;
2472            if (qname.startsWith("{")) {
2473                index = qname.lastIndexOf('}');
2474                if (index != -1)
2475                    namespace = qname.substring(1, index);
2476            } else {
2477                index = qname.lastIndexOf(":");
2478                String JavaDoc prefix = null;
2479                if (index != -1) {
2480                    prefix = qname.substring(0, index);
2481                    namespace = reconstructionDeclarations.getNamespaceURI(prefix);
2482                    if (namespace == null)
2483                        throw new XQueryException("Could not find prefix : " + prefix);
2484                }
2485            }
2486            String JavaDoc localname = qname.substring(index + 1);
2487            evalResultNamespace = (namespace == null) ? EMPTY_STRING : namespace;
2488            evalResultValue = (localname == null) ? EMPTY_STRING : localname;
2489        }
2490    }
2491
2492    // TODO danger when data will be treated in QMEM
2493
public void visit(FunctionDATA arg) throws XQueryException {
2494        evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
2495        arg.accept(evalVisitor);
2496        if (evalVisitor.getResValue() == null) {
2497            throw new XQueryException("Could not evaluate : " + arg);
2498        }
2499        String JavaDoc res = evalVisitor.getResValue().toString();
2500        characters(res.toCharArray(),0,res.length());
2501    }
2502
2503    public void visit(Value arg) throws XQueryException {
2504        String JavaDoc text = arg.getValue();
2505        if (evalNeeded) {
2506            evalResultNamespace = EMPTY_STRING;
2507            if (evalResultValue != null && evalResultValue.length() > 0)
2508                evalResultValue += ' ' + text;
2509            else
2510                evalResultValue = text;
2511        } else {
2512            characters(text.toCharArray(), 0, text.length());
2513        }
2514    }
2515
2516    private void outputVariable(Variable arg) throws XQueryException {
2517        if (!noResultSet) {
2518            int nodeAccessor = Step.NONE;
2519            if (arg.getExpression() instanceof LocatedExpression) {
2520                LocatedExpression tmpLoc = (LocatedExpression) arg.getExpression();
2521                ArrayList steps = tmpLoc.getSteps();
2522                nodeAccessor = tmpLoc.getNodeAccessor();
2523                if (nodeAccessor == Step.NONE) {
2524                    int lastPosition = steps.size() - 1;
2525                    Step lastStep = (Step) steps.get(lastPosition);
2526                    if (lastStep.getStepKind() % 16 != 0) {
2527                        tmpLoc.setNodeAccessor(lastStep.getStepKind());
2528                        nodeAccessor = tmpLoc.getNodeAccessor();
2529                        steps.remove(lastPosition);
2530                    }
2531                }
2532                // Step lastStep = (Step) steps.get(steps.size() - 1);
2533
// XQueryExpression lastStepExpr = lastStep.getExpression();
2534
// if (lastStepExpr instanceof NodeTest && ((NodeTest) lastStepExpr).getKind() == NodeKind.TEXT)
2535
// if (lastStep.getAxis() == Axis.CHILD)
2536
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_TEXT;
2537
// else if (lastStep.getAxis() == Axis.SELF)
2538
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_SELF_TEXT;
2539
}
2540            generate(arg.getStringValue(), nodeAccessor, arg.getLoopIDs());
2541        }
2542    }
2543
2544    public void visit(Variable arg) throws XQueryException { // TODO !!!!! nearly the SAME as Element
2545

2546        if (evalNeeded) {
2547            evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
2548            arg.accept(evalVisitor);
2549            evalResultNamespace = EMPTY_STRING;
2550            Comparable JavaDoc comp = evalVisitor.getResValue();
2551            if (comp == null)
2552                evalResultValue = EMPTY_STRING;
2553            else {
2554                if (evalResultValue != null && evalResultValue.length() > 0)
2555                    evalResultValue += " " + comp.toString();
2556                else
2557                    evalResultValue = comp.toString();
2558            }
2559            return;
2560        }
2561
2562        boolean putPrefixMapping = false;
2563
2564        if (hasPrefixMapping) {
2565            startPrefixMapping(true);
2566            hasPrefixMapping = false;
2567            putPrefixMapping = true;
2568        }
2569
2570        boolean isSkolemID = false;
2571        boolean isDependID = false;
2572        noReconstructor = true;
2573        if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
2574            isSkolemID = true;
2575        ArrayList dependIDs = arg.getDependIDs();
2576        if (dependIDs != null && !dependIDs.isEmpty())
2577            isDependID = true;
2578        boolean loop = arg.getLoop();
2579
2580        // CASE : this element has no skolem ids
2581
if (!isSkolemID) {
2582            // CASE : the element is written until there are no more results available
2583
if (loop) {
2584                // no not continue if dependIDs changed
2585
if (this.noResultSet && dependIDs != lastDependIDs)
2586                    return;
2587                while (true) {
2588                    outputVariable(arg);
2589                    noReconstructor = true;
2590                    if (hasNext())
2591                        nextAsSAX();
2592                    else
2593                        break;
2594                }
2595            }
2596            // CASE : no loop and element has depend ids
2597
else if (isDependID) {
2598                noNext = false;
2599                boolean changeDependIDs = true;
2600                /// !!! DANGER !!! THIS is stupid code!!! ( )
2601
try {
2602                    this.setIdentifiers(false);
2603                } catch (XQueryException e) {
2604                    changeDependIDs = false;
2605                }
2606                while (!isEmpty(dependIDs) && changeDependIDs) {
2607                    // case of namespace in top element
2608
// set lastSkolemIDsSize
2609
if (skolemIDs != null)
2610                        lastSkolemIDsSize = skolemIDs.size();
2611                    outputVariable(arg);
2612                    if (!hasNext())
2613                        break;
2614                    changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
2615                    if (!changeDependIDs) {
2616                        noNext = false;
2617                        break;
2618                    } else if (!isEmpty(dependIDs))
2619                        noNext = false;
2620                    if (!noNext) {
2621                        noReconstructor = true;
2622                        if (!hasNext())
2623                            break;
2624                        identifierCopy(currentIdentifiers, lastIdentifiers);
2625                        nextAsSAX();
2626                        this.setIdentifiers(true);
2627                    }
2628                    if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
2629                        noNext = true;
2630                }
2631            } else {
2632                outputVariable(arg);
2633            }
2634        }
2635        // there is at least a skolemID
2636
else {
2637
2638            // set the current identifier and the next
2639
if (isSkolemID && !arg.getRoot()) {
2640                this.setIdentifiers(false);
2641            }
2642            // there is no dependID
2643
if (dependIDs == null && !arg.getRoot()) {
2644                // CODE NOT USED !!! AS FAR AS I CAN TELL
2645
if (loop) {
2646                    while (true) {
2647                        // set lastSkolemIDsSize
2648
if (skolemIDs != null)
2649                            lastSkolemIDsSize = skolemIDs.size();
2650                        outputVariable(arg);
2651                        // WRITE STOP
2652
noReconstructor = true;
2653                        noNext = false;
2654                        if (hasNext())
2655                            nextAsSAX();
2656                        else
2657                            break;
2658                    }
2659                } else {
2660                    // set lastSkolemIDsSize
2661
if (skolemIDs != null)
2662                        lastSkolemIDsSize = skolemIDs.size();
2663                    // WRITE SONS
2664
outputVariable(arg);
2665                }
2666            } else // dependIDs != null or arg element is root
2667
{
2668                noNext = false;
2669                if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
2670                    boolean changeDependIDs = true;
2671
2672                    boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
2673                    // stop if the skolemIDs changed, and that dependIDs does not have an incidence
2674
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
2675                        return;
2676                    }
2677
2678                    int firstDependIDPosition = 0;
2679                    if (dependIDs != null && !dependIDs.isEmpty()) {
2680                        firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
2681                    }
2682                    int skipEntries = -1;
2683                    if (firstDependIDPosition > skolemIDs.size()) {
2684                        skipEntries = lastSkolemIDsSize;
2685                        while (!changeSkolemIDs && isEmpty(dependIDs)) {
2686                            if (!hasNext())
2687                                break;
2688                            identifierCopy(currentIdentifiers, lastIdentifiers);
2689                            nextAsSAX();
2690                            this.setIdentifiers(true);
2691                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
2692                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
2693                        }
2694                    }
2695                    while (!isEmpty(dependIDs) && changeDependIDs) {
2696                        // set lastSkolemIDsSize
2697
if (skolemIDs != null)
2698                            lastSkolemIDsSize = skolemIDs.size();
2699                        outputVariable(arg);
2700                        if (!hasNext())
2701                            break;
2702                        if (skipEntries == -1) {
2703                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
2704                            if (!changeDependIDs) {
2705                                noNext = false;
2706                                break;
2707                            } else if (!isEmpty(dependIDs))
2708                                noNext = false;
2709                        }
2710                        // ----------------------------
2711
// ADDED
2712
//-----------------------------
2713
else {
2714                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
2715                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
2716                            if (!changeSkolemIDs) {
2717                                noNext = false;
2718                                boolean noDependIDs = true;
2719                                boolean makeBreak = false;
2720                                noReInit = false;
2721                                while (!changeSkolemIDs && noDependIDs) {
2722                                    noReconstructor = true;
2723                                    if (!hasNext()) {
2724                                        makeBreak = true;
2725                                        break;
2726                                    }
2727                                    identifierCopy(currentIdentifiers, lastIdentifiers);
2728                                    nextAsSAX();
2729                                    this.setIdentifiers(true);
2730                                    changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
2731                                    noDependIDs = isEmpty(dependIDs);
2732                                }
2733                                if (makeBreak)
2734                                    break;
2735                                noNext = true;
2736                                if (!noDependIDs)
2737                                    noReInit = true;
2738                                changeDependIDs = true;
2739                            } else if (!isEmpty(dependIDs))
2740                                noNext = false;
2741                        }
2742                        // ----------------------------
2743
// END ADDED
2744
//-----------------------------
2745
if (!noNext && !changeSkolemIDs) {
2746                            noReconstructor = true;
2747                            if (!hasNext())
2748                                break;
2749                            identifierCopy(currentIdentifiers, lastIdentifiers);
2750                            nextAsSAX();
2751                            this.setIdentifiers(true);
2752                        }
2753                        if (skipEntries == -1) {
2754                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
2755                                noNext = true;
2756                        } else {
2757                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
2758                                noNext = false; // CHANGE 03/07/2002 was initially true
2759
}
2760                    }
2761                } else {
2762                    boolean changeSkolemIDs = false;
2763                    while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
2764                        // set lastSkolemIDsSize
2765
if (skolemIDs != null)
2766                            lastSkolemIDsSize = skolemIDs.size();
2767                        // set last dependIDs
2768
lastDependIDs = dependIDs;
2769                        outputVariable(arg);
2770                        if (!hasNext())
2771                            break;
2772
2773                        if (!arg.getRoot())
2774                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
2775                        if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
2776                            noReconstructor = true;
2777                            if (!hasNext())
2778                                break;
2779                            identifierCopy(currentIdentifiers, lastIdentifiers);
2780                            nextAsSAX();
2781                            this.setIdentifiers(true);
2782                        }
2783                        if (changeSkolemIDs)
2784                            noNext = true;
2785                        if (arg.getRoot())
2786                            break;
2787                    }
2788                    // while (!changeSkolemIDs);
2789
}
2790                // noNext = true;
2791
}
2792        }
2793        noReconstructor = false;
2794
2795        if (putPrefixMapping) {
2796            hasPrefixMapping = true;
2797            putPrefixMapping = false;
2798            endPrefixMapping(true);
2799        }
2800    }
2801
2802    public void visit(XMLComment arg) throws XQueryException {
2803        String JavaDoc comment = null;
2804        evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
2805        arg.getComment().accept(evalVisitor);
2806        Comparable JavaDoc comp = evalVisitor.getResValue();
2807        if (comp != null)
2808            comment = comp.toString();
2809        try {
2810            if (comment != null)
2811                reconstructionHandler.comment(comment.toCharArray(), 0, comment.length());
2812        } catch (SAXException e) {
2813            throw new XQueryException(e.getMessage());
2814        }
2815    }
2816
2817    private void outputXMLProcessingInstruction(XMLProcessingInstruction arg) throws XQueryException {
2818        String JavaDoc name = null;
2819        String JavaDoc value = null;
2820
2821        XQueryExpression expr = arg.getExpression1();
2822        evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
2823        expr.accept(evalVisitor);
2824        Comparable JavaDoc comp = evalVisitor.getResValue();
2825        name = (comp == null) ? null : comp.toString();
2826        expr = arg.getExpression2();
2827        evalVisitor.setReturnType(EvaluationVisitor.VALUE_TYPE);
2828        expr.accept(evalVisitor);
2829        comp = evalVisitor.getResValue();
2830        value = (comp == null) ? EMPTY_STRING : comp.toString();
2831        try {
2832            reconstructionHandler.processingInstruction(name, value);
2833        } catch (SAXException e) {
2834            throw new XQueryException(e.getMessage());
2835        }
2836    }
2837
2838    public void visit(XMLProcessingInstruction arg) throws XQueryException {
2839        boolean isSkolemID = false;
2840        boolean isDependID = false;
2841        boolean putPrefixMapping = false;
2842        noReconstructor = true;
2843        skolemIDs = arg.getSkolemIDs();
2844        if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
2845            isSkolemID = true;
2846        ArrayList dependIDs = arg.getDependIDs();
2847        if (dependIDs != null && !dependIDs.isEmpty())
2848            isDependID = true;
2849        boolean loop = arg.getLoop();
2850
2851        // CASE : this element has no skolem ids
2852
if (!isSkolemID) {
2853            // CASE : the element is written until there are no more results available
2854
if (loop) {
2855                // no not continue if dependIDs changed
2856
if (this.noResultSet && dependIDs != lastDependIDs)
2857                    return;
2858                while (true) {
2859                    // WRITE SONS
2860
boolean previousRoot = root;
2861                    root = false;
2862                    outputXMLProcessingInstruction(arg);
2863                    root = previousRoot;
2864                    noReconstructor = true;
2865                    if (hasNext())
2866                        nextAsSAX();
2867                    else
2868                        break;
2869                }
2870            }
2871            // CASE : no loop and element has depend ids
2872
else if (isDependID) {
2873                noNext = false;
2874                boolean changeDependIDs = true;
2875                /// !!! DANGER !!! THIS is stupid code!!! ( )
2876
try {
2877                    this.setIdentifiers(false);
2878                } catch (XQueryException e) {
2879                    changeDependIDs = false;
2880                }
2881                while (!isEmpty(dependIDs) && changeDependIDs) {
2882                    // WRITE SONS
2883
boolean previousRoot = root;
2884                    root = false;
2885                    outputXMLProcessingInstruction(arg);
2886                    root = previousRoot;
2887                    if (!hasNext())
2888                        break;
2889                    changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
2890                    if (!changeDependIDs) {
2891                        noNext = false;
2892                        break;
2893                    } else if (!isEmpty(dependIDs))
2894                        noNext = false;
2895                    if (!noNext) {
2896                        noReconstructor = true;
2897                        if (!hasNext())
2898                            break;
2899                        identifierCopy(currentIdentifiers, lastIdentifiers);
2900                        nextAsSAX();
2901                        this.setIdentifiers(true);
2902                    }
2903                    if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
2904                        noNext = true;
2905                }
2906            } else {
2907                // WRITE SONS
2908
boolean previousRoot = root;
2909                root = false;
2910                outputXMLProcessingInstruction(arg);
2911                root = previousRoot;
2912            }
2913        }
2914        // there is at least a skolemID
2915
else {
2916
2917            // set the current identifier and the next
2918
if (isSkolemID && !arg.getRoot()) {
2919                this.setIdentifiers(false);
2920            }
2921            // there is no dependID
2922
if (dependIDs == null && !arg.getRoot()) {
2923                // CODE NOT USED !!! AS FAR AS I CAN TELL
2924
if (loop) {
2925                    while (true) {
2926                        // WRITE SONS
2927
boolean previousRoot = root;
2928                        root = false;
2929                        outputXMLProcessingInstruction(arg);
2930                        root = previousRoot;
2931                        noReconstructor = true;
2932                        noNext = false;
2933                        if (hasNext())
2934                            nextAsSAX();
2935                        else
2936                            break;
2937                    }
2938                } else {
2939                    // WRITE SONS
2940
boolean previousRoot = root;
2941                    root = false;
2942                    outputXMLProcessingInstruction(arg);
2943                    root = previousRoot;
2944                }
2945            } else // dependIDs != null or arg element is root
2946
{
2947                noNext = false;
2948                if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
2949                    boolean changeDependIDs = true;
2950                    boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
2951                    // stop if the skolemIDs changed, and that dependIDs does not have an incidence
2952
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
2953                        return;
2954                    }
2955
2956                    int firstDependIDPosition = 0;
2957                    if (dependIDs != null && !dependIDs.isEmpty()) {
2958                        firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
2959                    }
2960                    int skipEntries = -1;
2961                    if (firstDependIDPosition > skolemIDs.size()) {
2962                        skipEntries = lastSkolemIDsSize;
2963                        while (!changeSkolemIDs && isEmpty(dependIDs)) {
2964                            if (!hasNext())
2965                                break;
2966                            identifierCopy(currentIdentifiers, lastIdentifiers);
2967                            nextAsSAX();
2968                            this.setIdentifiers(true);
2969                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
2970                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
2971                        }
2972                    }
2973                    while (!isEmpty(dependIDs) && changeDependIDs) {
2974                        // WRITE SONS
2975
boolean previousRoot = root;
2976                        root = false;
2977                        outputXMLProcessingInstruction(arg);
2978                        root = previousRoot;
2979                        if (!hasNext())
2980                            break;
2981                        if (skipEntries == -1) {
2982                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
2983                            if (!changeDependIDs) {
2984                                noNext = false;
2985                                break;
2986                            } else if (!isEmpty(dependIDs))
2987                                noNext = false;
2988                        }
2989                        // ----------------------------
2990
// ADDED
2991
//-----------------------------
2992
else {
2993                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
2994                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
2995                            if (!changeSkolemIDs) {
2996                                noNext = false;
2997                                boolean noDependIDs = true;
2998                                boolean makeBreak = false;
2999                                noReInit = false;
3000                                while (!changeSkolemIDs && noDependIDs) {
3001                                    noReconstructor = true;
3002                                    if (!hasNext()) {
3003                                        makeBreak = true;
3004                                        break;
3005                                    }
3006                                    identifierCopy(currentIdentifiers, lastIdentifiers);
3007                                    nextAsSAX();
3008                                    this.setIdentifiers(true);
3009                                    changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
3010                                    noDependIDs = isEmpty(dependIDs);
3011                                }
3012                                if (makeBreak)
3013                                    break;
3014                                noNext = true;
3015                                if (!noDependIDs)
3016                                    noReInit = true;
3017                                changeDependIDs = true;
3018                            } else if (!isEmpty(dependIDs))
3019                                noNext = false;
3020                        }
3021                        // ----------------------------
3022
// END ADDED
3023
//-----------------------------
3024
if (!noNext && !changeSkolemIDs) {
3025                            noReconstructor = true;
3026                            if (!hasNext())
3027                                break;
3028                            identifierCopy(currentIdentifiers, lastIdentifiers);
3029                            nextAsSAX();
3030                            this.setIdentifiers(true);
3031                        }
3032                        if (skipEntries == -1) {
3033                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
3034                                noNext = true;
3035                        } else {
3036                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
3037                                noNext = false; // CHANGE 03/07/2002 was initially true
3038
}
3039                    }
3040                } else {
3041                    boolean changeSkolemIDs = false;
3042                    while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
3043                        // set last dependIDs
3044
lastDependIDs = dependIDs;
3045                        // WRITE SONS
3046
boolean previousRoot = root;
3047                        root = false;
3048                        outputXMLProcessingInstruction(arg);
3049                        root = previousRoot;
3050                        if (!hasNext())
3051                            break;
3052                        if (!arg.getRoot())
3053                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
3054                        if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
3055                            noReconstructor = true;
3056                            if (!hasNext())
3057                                break;
3058                            identifierCopy(currentIdentifiers, lastIdentifiers);
3059                            nextAsSAX();
3060                            this.setIdentifiers(true);
3061                        }
3062                        if (changeSkolemIDs)
3063                            noNext = true;
3064                        if (arg.getRoot())
3065                            break;
3066                    }
3067                    // while (!changeSkolemIDs);
3068
}
3069                // noNext = true;
3070
}
3071        }
3072        noReconstructor = false;
3073    }
3074
3075    public void visit(XQueryExpression arg) throws XQueryException {
3076        throw new XQueryException("Class " + arg.getClass().getName() + " not supported in ReconstructionVisitor.");
3077    }
3078
3079    public void visit(XQueryExpressionSequence arg) throws XQueryException { // TODO !!!!! nearly the SAME as Element
3080

3081        boolean isSkolemID = false;
3082        boolean isDependID = false;
3083        noReconstructor = true;
3084        skolemIDs = arg.getSkolemIDs();
3085        if ((skolemIDs != null && !skolemIDs.isEmpty()) || arg.getRoot())
3086            isSkolemID = true;
3087        ArrayList dependIDs = arg.getDependIDs();
3088        if (dependIDs != null && !dependIDs.isEmpty())
3089            isDependID = true;
3090        boolean loop = arg.getLoop();
3091
3092        // CASE : this element has no skolem ids
3093
if (!isSkolemID) {
3094            // CASE : the element is written until there are no more results available
3095
if (loop) {
3096                // no not continue if dependIDs changed
3097
if (this.noResultSet && dependIDs != lastDependIDs)
3098                    return;
3099                while (true) {
3100                    // WRITE SONS
3101
ArrayList subExpressions = arg.getSubExpressions();
3102                    if (subExpressions != null) {
3103                        boolean previousRoot = root;
3104                        root = false;
3105                        for (int i = 0; i < subExpressions.size(); i++) {
3106                            XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
3107                            ((XQueryExpression) subExpressions.get(i)).accept(this);
3108                            this.skolemIDs = arg.getSkolemIDs();
3109                        }
3110                        root = previousRoot;
3111                    }
3112                    noReconstructor = true;
3113                    if (hasNext())
3114                        nextAsSAX();
3115                    else
3116                        break;
3117                }
3118            }
3119            // CASE : no loop and element has depend ids
3120
else if (isDependID) {
3121                noNext = false;
3122                boolean changeDependIDs = true;
3123                /// !!! DANGER !!! THIS is stupid code!!! ( )
3124
try {
3125                    this.setIdentifiers(false);
3126                } catch (XQueryException e) {
3127                    changeDependIDs = false;
3128                }
3129                while (!isEmpty(dependIDs) && changeDependIDs) {
3130                    // case of namespace in top element
3131
// set lastSkolemIDsSize
3132
if (skolemIDs != null)
3133                        lastSkolemIDsSize = skolemIDs.size();
3134                    // WRITE SONS
3135
ArrayList subExpressions = arg.getSubExpressions();
3136                    if (subExpressions != null) {
3137                        boolean previousRoot = root;
3138                        root = false;
3139                        for (int i = 0; i < subExpressions.size(); i++) {
3140                            XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
3141                            ((XQueryExpression) subExpressions.get(i)).accept(this);
3142                            this.skolemIDs = arg.getSkolemIDs();
3143                            if (skolemIDs != null)
3144                                lastSkolemIDsSize = skolemIDs.size();
3145                        }
3146                        root = previousRoot;
3147                    }
3148                    if (!hasNext())
3149                        break;
3150                    changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
3151                    if (!changeDependIDs) {
3152                        noNext = false;
3153                        break;
3154                    } else if (!isEmpty(dependIDs))
3155                        noNext = false;
3156                    if (!noNext) {
3157                        noReconstructor = true;
3158                        if (!hasNext())
3159                            break;
3160                        identifierCopy(currentIdentifiers, lastIdentifiers);
3161                        nextAsSAX();
3162                        this.setIdentifiers(true);
3163                    }
3164                    if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
3165                        noNext = true;
3166                }
3167            } else {
3168                // WRITE SONS
3169
ArrayList subExpressions = arg.getSubExpressions();
3170                if (subExpressions != null) {
3171                    boolean previousRoot = root;
3172                    root = false;
3173                    for (int i = 0; i < subExpressions.size(); i++) {
3174                        XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
3175                        ((XQueryExpression) subExpressions.get(i)).accept(this);
3176                        this.skolemIDs = arg.getSkolemIDs();
3177                    }
3178                    root = previousRoot;
3179                }
3180            }
3181        }
3182        // there is at least a skolemID
3183
else {
3184
3185            // set the current identifier and the next
3186
if (isSkolemID && !arg.getRoot()) {
3187                this.setIdentifiers(false);
3188            }
3189            // there is no dependID
3190
if (dependIDs == null && !arg.getRoot()) {
3191                // CODE NOT USED !!! AS FAR AS I CAN TELL
3192
if (loop) {
3193                    while (true) {
3194                        // set lastSkolemIDsSize
3195
if (skolemIDs != null)
3196                            lastSkolemIDsSize = skolemIDs.size();
3197                        // WRITE SONS
3198
ArrayList subExpressions = arg.getSubExpressions();
3199                        if (subExpressions != null) {
3200                            boolean previousRoot = root;
3201                            root = false;
3202                            for (int i = 0; i < subExpressions.size(); i++) {
3203                                XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
3204                                ((XQueryExpression) subExpressions.get(i)).accept(this);
3205                                this.skolemIDs = arg.getSkolemIDs();
3206                                if (skolemIDs != null)
3207                                    lastSkolemIDsSize = skolemIDs.size();
3208                            }
3209                            root = previousRoot;
3210                        }
3211
3212                        // WRITE STOP
3213
noReconstructor = true;
3214                        noNext = false;
3215                        if (hasNext())
3216                            nextAsSAX();
3217                        else
3218                            break;
3219                    }
3220                } else {
3221                    // set lastSkolemIDsSize
3222
if (skolemIDs != null)
3223                        lastSkolemIDsSize = skolemIDs.size();
3224                    // WRITE SONS
3225
ArrayList subExpressions = arg.getSubExpressions();
3226                    if (subExpressions != null) {
3227                        boolean previousRoot = root;
3228                        root = false;
3229                        for (int i = 0; i < subExpressions.size(); i++) {
3230                            XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
3231                            ((XQueryExpression) subExpressions.get(i)).accept(this);
3232                            this.skolemIDs = arg.getSkolemIDs();
3233                            if (skolemIDs != null)
3234                                lastSkolemIDsSize = skolemIDs.size();
3235                        }
3236                        root = previousRoot;
3237                    }
3238                }
3239            } else // dependIDs != null or arg element is root
3240
{
3241                noNext = false;
3242                if (!arg.getRoot() && lastSkolemIDsSize < skolemIDs.size()) {
3243                    boolean changeDependIDs = true;
3244
3245                    boolean changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
3246                    // stop if the skolemIDs changed, and that dependIDs does not have an incidence
3247
if (dependIDs != null && dependIDs.isEmpty() && changeSkolemIDs) {
3248                        return;
3249                    }
3250
3251                    int firstDependIDPosition = 0;
3252                    if (dependIDs != null && !dependIDs.isEmpty()) {
3253                        firstDependIDPosition = getPosition((Variable) dependIDs.get(0)) + 1;
3254                    }
3255                    int skipEntries = -1;
3256                    if (firstDependIDPosition > skolemIDs.size()) {
3257                        skipEntries = lastSkolemIDsSize;
3258                        while (!changeSkolemIDs && isEmpty(dependIDs)) {
3259                            if (!hasNext())
3260                                break;
3261                            identifierCopy(currentIdentifiers, lastIdentifiers);
3262                            nextAsSAX();
3263                            this.setIdentifiers(true);
3264                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, lastSkolemIDsSize);
3265                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, lastSkolemIDsSize);
3266                        }
3267                    }
3268                    while (!isEmpty(dependIDs) && changeDependIDs) {
3269                        // set lastSkolemIDsSize
3270
if (skolemIDs != null)
3271                            lastSkolemIDsSize = skolemIDs.size();
3272                        // WRITE SONS
3273
ArrayList subExpressions = arg.getSubExpressions();
3274                        if (subExpressions != null) {
3275                            boolean previousRoot = root;
3276                            root = false;
3277                            for (int i = 0; i < subExpressions.size(); i++) {
3278                                XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
3279                                ((XQueryExpression) subExpressions.get(i)).accept(this);
3280                                this.skolemIDs = arg.getSkolemIDs();
3281                                if (skolemIDs != null)
3282                                    lastSkolemIDsSize = skolemIDs.size();
3283                            }
3284                            root = previousRoot;
3285                        }
3286                        if (!hasNext())
3287                            break;
3288                        if (skipEntries == -1) {
3289                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, firstDependIDPosition - 1);
3290                            if (!changeDependIDs) {
3291                                noNext = false;
3292                                break;
3293                            } else if (!isEmpty(dependIDs))
3294                                noNext = false;
3295                        }
3296                        // ----------------------------
3297
// ADDED
3298
//-----------------------------
3299
else {
3300                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
3301                            changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, skolemIDs, dependIDs, skipEntries);
3302                            if (!changeSkolemIDs) {
3303                                noNext = false;
3304                                boolean noDependIDs = true;
3305                                boolean makeBreak = false;
3306                                noReInit = false;
3307                                while (!changeSkolemIDs && noDependIDs) {
3308                                    noReconstructor = true;
3309                                    if (!hasNext()) {
3310                                        makeBreak = true;
3311                                        break;
3312                                    }
3313                                    identifierCopy(currentIdentifiers, lastIdentifiers);
3314                                    nextAsSAX();
3315                                    this.setIdentifiers(true);
3316                                    changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries);
3317                                    noDependIDs = isEmpty(dependIDs);
3318                                }
3319                                if (makeBreak)
3320                                    break;
3321                                noNext = true;
3322                                if (!noDependIDs)
3323                                    noReInit = true;
3324                                changeDependIDs = true;
3325                            } else if (!isEmpty(dependIDs))
3326                                noNext = false;
3327                        }
3328                        // ----------------------------
3329
// END ADDED
3330
//-----------------------------
3331
if (!noNext && !changeSkolemIDs) {
3332                            noReconstructor = true;
3333                            if (!hasNext())
3334                                break;
3335                            identifierCopy(currentIdentifiers, lastIdentifiers);
3336                            nextAsSAX();
3337                            this.setIdentifiers(true);
3338                        }
3339                        if (skipEntries == -1) {
3340                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs))
3341                                noNext = true;
3342                        } else {
3343                            if (changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs, skipEntries))
3344                                noNext = false; // CHANGE 03/07/2002 was initially true
3345
}
3346                    }
3347                } else {
3348                    boolean changeSkolemIDs = false;
3349                    while (arg.getRoot() || (!isEmpty(dependIDs) && !changeSkolemIDs)) {
3350                        // set lastSkolemIDsSize
3351
if (skolemIDs != null)
3352                            lastSkolemIDsSize = skolemIDs.size();
3353                        // set last dependIDs
3354
lastDependIDs = dependIDs;
3355                        // WRITE SONS
3356
ArrayList subExpressions = arg.getSubExpressions();
3357                        if (subExpressions != null) {
3358                            boolean previousRoot = root;
3359                            root = false;
3360                            byte num = 0;
3361                            for (int i = 0; i < subExpressions.size(); i++) {
3362                                if (!((XQueryExpression) subExpressions.get(i) instanceof Value))
3363                                    num++;
3364                                if (num > 1)
3365                                    break;
3366                            }
3367                            for (int i = 0; i < subExpressions.size(); i++) {
3368                                XQueryExpression expr = (XQueryExpression) subExpressions.get(i);
3369                                // CHANGED 10/04/2003
3370
if (num == 1 && arg.getRoot())
3371                                    expr.setRoot(true);
3372                                //if (subExpressions.size() == 1 && arg.getRoot()) expr.setRoot(true);
3373
//((XQueryExpression) subExpressions.get(i)).accept(this);
3374
expr.accept(this);
3375                                this.skolemIDs = arg.getSkolemIDs();
3376                                if (skolemIDs != null)
3377                                    lastSkolemIDsSize = skolemIDs.size();
3378                            }
3379                            root = previousRoot;
3380                        }
3381                        if (!hasNext())
3382                            break;
3383
3384                        if (!arg.getRoot())
3385                            changeSkolemIDs = changeSkolemIDs(currentIdentifiers, nextIdentifiers, skolemIDs);
3386                        if (!noNext && !arg.getRoot() && !isEmpty(dependIDs) && !changeSkolemIDs) {
3387                            noReconstructor = true;
3388                            if (!hasNext())
3389                                break;
3390                            identifierCopy(currentIdentifiers, lastIdentifiers);
3391                            nextAsSAX();
3392                            this.setIdentifiers(true);
3393                        }
3394                        if (changeSkolemIDs)
3395                            noNext = true;
3396                        if (arg.getRoot())
3397                            break;
3398                    }
3399                    // while (!changeSkolemIDs);
3400
}
3401                // noNext = true;
3402
}
3403        }
3404        noReconstructor = false;
3405    }
3406
3407    /*
3408    returns
3409    -1 if error
3410    0 if no change
3411    n for change in order n element
3412     */

3413    private int identifierCompare(Object JavaDoc[] list1, Object JavaDoc[] list2) throws ReconstructionException {
3414        if (list1 == null && list2 != null) {
3415            return list2.length;
3416        }
3417        if (list1 == null && list2 == null) {
3418            throw new ReconstructionException("Incorrects argumments in method identifierCompare");
3419        }
3420        int len1 = list1.length;
3421        // if (len1 > skolemSize) len1 = skolemSize;
3422
int len2 = list2.length;
3423        // if (len2 > skolemSize) len2 = skolemSize;
3424
int i = 0;
3425        while (i < len1 && i < len2) {
3426            if (list1[i] == null || list2[i] == null) {
3427                return i + 1;
3428            }
3429            if (!list1[i].equals(list2[i])) {
3430                return i + 1;
3431            }
3432            i++;
3433        }
3434        if (len1 != len2) {
3435            return i + 1;
3436        }
3437        return 0;
3438    }
3439
3440    private boolean changeDependIDs(Object JavaDoc[] list1, Object JavaDoc[] list2, ArrayList dependIDs) throws ReconstructionException {
3441        return changeDependIDs(list1, list2, null, dependIDs, -1);
3442    }
3443
3444    private boolean changeDependIDs(Object JavaDoc[] list1, Object JavaDoc[] list2, ArrayList skolemIDs, ArrayList dependIDs, int maxSkolemSize) throws ReconstructionException {
3445        if (list1 == null && list2 != null) {
3446            return true;
3447        }
3448        if (list1 == null && list2 == null) {
3449            return true;
3450        }
3451
3452        if (skolemIDs != null) {
3453            int position = -1;
3454            for (int i = 0; i < maxSkolemSize; i++) {
3455                position = getPosition((Variable) skolemIDs.get(i));
3456                //if (list1[position] == null && list2[position] == null) continue; // 2002/09/23
3457
if (list1[position] == null || list2[position] == null)
3458                    return true;
3459                if (!list1[position].equals(list2[position])) {
3460                    return false;
3461                }
3462            }
3463        }
3464        for (int j = 0; j < dependIDs.size(); j++) {
3465            int position = getPosition((Variable) dependIDs.get(j));
3466            if (list1[position] == null || list2[position] == null)
3467                return true;
3468            if (!list1[position].equals(list2[position])) {
3469                return true;
3470            }
3471        }
3472        return false;
3473    }
3474
3475    private boolean changeSkolemIDs(Object JavaDoc[] list1, Object JavaDoc[] list2, ArrayList skolemIDs) throws ReconstructionException {
3476        return changeSkolemIDs(list1, list2, skolemIDs, (skolemIDs == null) ? 0 : skolemIDs.size());
3477    }
3478
3479    private boolean changeSkolemIDs(Object JavaDoc[] list1, Object JavaDoc[] list2, ArrayList skolemIDs, int maxSkolemSize) throws ReconstructionException {
3480        int position = -1;
3481        for (int j = 0; j < maxSkolemSize; j++) {
3482            position = getPosition((Variable) skolemIDs.get(j));
3483            if (list1[position] == null || list2[position] == null)
3484                return true;
3485            if (!list1[position].equals(list2[position])) {
3486                return true;
3487            }
3488        }
3489        return false;
3490    }
3491
3492    private void identifierCopy(Object JavaDoc[] original, Object JavaDoc[] copy) {
3493        if (copy == null)
3494            copy = new Object JavaDoc[size];
3495        for (int i = 0; i < size; i++)
3496            copy[i] = original[i];
3497    }
3498
3499    private boolean isEmpty(ArrayList dependIDs) throws ReconstructionException {
3500        if (dependIDs == null)
3501            return true;
3502        int countIsEmpty = 0;
3503        for (int i = 0; i < dependIDs.size(); i++) {
3504            Object JavaDoc identifier = currentIdentifiers[getPosition((Variable) dependIDs.get(i))];
3505            if (identifier == null || (identifier instanceof ArrayList && ((ArrayList) identifier).size() == 1 && ((ArrayList) identifier).get(0) == null))
3506                countIsEmpty++;
3507        }
3508        if (countIsEmpty == dependIDs.size()) {
3509            return true;
3510        }
3511        return false;
3512    }
3513
3514    private int getPosition(Variable variable) throws ReconstructionException {
3515        int position = varList.indexOf(variable);
3516        if (position == -1)
3517            throw new ReconstructionException("This variable " + variable + " is not defined in the list of variables.");
3518        return position;
3519    }
3520
3521    private String JavaDoc fetch(String JavaDoc path, int nodeAccessor, String JavaDoc loopid) throws XQueryException {
3522        try {
3523            return xdbcResultSet.fetch(path, nodeAccessor, loopid, psvisp);
3524        } catch (XMLDBCException e) {
3525            throw new XQueryException(e.getMessage());
3526        }
3527    }
3528
3529    private void generate(String JavaDoc path, int nodeAccessor, String JavaDoc loopid) throws XQueryException {
3530        // if (nodeAccessor == XDBCResultSetInterface.NODE_ACCESSOR_SELF_TEXT || nodeAccessor == XDBCResultSetInterface.NODE_ACCESSOR_TEXT)
3531
// hasCharacters = true;
3532
// else
3533
// hasCharacters = false;
3534
try {
3535            xdbcResultSet.generate(path, nodeAccessor, loopid, psvisp);
3536        } catch (XMLDBCException e) {
3537            throw new XQueryException(e.getMessage());
3538        }
3539    }
3540
3541    private void characters(char[] ch, int start, int length) throws XQueryException {
3542        try {
3543            reconstructionHandler.characters(ch, start, length);
3544        } catch (SAXException e) {
3545            throw new XQueryException(e.getMessage());
3546        }
3547    }
3548
3549    private void startElement(String JavaDoc str1, String JavaDoc str2, String JavaDoc str3, AttributesImpl JavaDoc atts) throws XQueryException {
3550        try {
3551            reconstructionHandler.startElement(str1, str2, str3, atts);
3552        } catch (SAXException e) {
3553            throw new XQueryException(e.getMessage());
3554        }
3555    }
3556
3557    private void endElement(String JavaDoc str1, String JavaDoc str2, String JavaDoc str3) throws XQueryException {
3558        try {
3559            reconstructionHandler.endElement(str1, str2, str3);
3560        } catch (SAXException e) {
3561            throw new XQueryException(e.getMessage());
3562        }
3563    }
3564
3565    private boolean hasNext() throws XQueryException {
3566        try {
3567            return resultSet.hasNext();
3568        } catch (XMLDBCException e) {
3569            throw new XQueryException(e.getMessage());
3570        }
3571    }
3572
3573    private void nextAsSAX() throws XQueryException {
3574        try {
3575            resultSet.nextAsSAX();
3576        } catch (XMLDBCException e) {
3577            throw new XQueryException(e.getMessage());
3578        } catch (SAXException e) {
3579            throw new XQueryException(e.getMessage());
3580        }
3581    }
3582
3583    private void startPrefixMapping(boolean first) throws XQueryException {
3584        try {
3585            if (reconstructionDeclarations != null) {
3586                String JavaDoc prefix = null;
3587                ArrayList currentList = null;
3588                if (first)
3589                    currentList = new ArrayList(reconstructionDeclarations.getPrefixes());
3590                else
3591                    currentList = new ArrayList(reconstructionDeclarations.getDeclaredPrefixes());
3592                for (int i = 0; i < currentList.size(); i++) {
3593                    prefix = (String JavaDoc) currentList.get(i);
3594                    reconstructionHandler.startPrefixMapping(prefix, reconstructionDeclarations.getNamespaceURI(prefix));
3595                }
3596            }
3597        } catch (SAXException e) {
3598            throw new XQueryException(e.getMessage());
3599        }
3600    }
3601
3602    private void endPrefixMapping(boolean first) throws XQueryException {
3603        try {
3604            if (reconstructionDeclarations != null) {
3605                String JavaDoc prefix = null;
3606                ArrayList currentList = null;
3607                if (first)
3608                    currentList = new ArrayList(reconstructionDeclarations.getPrefixes());
3609                else
3610                    currentList = new ArrayList(reconstructionDeclarations.getDeclaredPrefixes());
3611                for (int i = 0; i < currentList.size(); i++) {
3612                    reconstructionHandler.endPrefixMapping((String JavaDoc) currentList.get(i));
3613                }
3614            }
3615        } catch (SAXException e) {
3616            throw new XQueryException(e.getMessage());
3617        }
3618    }
3619
3620    private void prepareAttributes(Element elt) throws XQueryException {
3621        listAttributes.clear();
3622        ArrayList attributes = elt.getAttributes();
3623        if (attributes != null) {
3624            for (int i = 0; i < attributes.size(); i++) {
3625                AttributeValuePair atti = (AttributeValuePair) attributes.get(i);
3626                if (atti.isXmlns())
3627                    reconstructionDeclarations.declarePrefix(((ValueString) atti.getAttributeName()).getStringValue(), ((ValueString) atti.getAttributeValue()).getStringValue());
3628                else
3629                    atti.accept(this);
3630            }
3631        }
3632    }
3633
3634    private void buildAttributes(Element arg) throws XQueryException {
3635        ArrayList sons = arg.getSubExpressions();
3636        if (sons == null)
3637            return;
3638        for (int i = arg.getComputedNSNum(); i < arg.getComputedNSNum() + arg.getComputedAttNum(); i++) {
3639            XQueryExpression son = (XQueryExpression) sons.get(i);
3640            // change LARS 01/07/04 this problem is catched later, avoid throwing exception if typing is lax
3641
// if (son.getQType().isMultiple()) {
3642
// throw new ReconstructionException("An element cannot have several attributes with the same name.");
3643
// }
3644
ArrayList dependIDs = son.getDependIDs();
3645            if (dependIDs == null || dependIDs.isEmpty()) {
3646                if (sons.size() == 1 && arg.getRoot())
3647                    son.setRoot(true);
3648                // evalNeeded = true;
3649
// son.accept(this);
3650
// evalNeeded = false;
3651

3652                QType qtype = son.getQType();
3653                String JavaDoc value = null;
3654                String JavaDoc nameSpaceAtt = ((QName) qtype.getName()).getNameSpace();
3655                String JavaDoc localNameAtt = ((QName) qtype.getName()).getLocalName();
3656                if (son instanceof Variable) {
3657                    XQueryExpression expr = ((Variable) son).getExpression();
3658                    if (!noResultSet)
3659                        value = fetch(son.getStringValue(), 0, son.getLoopIDs());
3660                } else if (son instanceof LocatedExpression) {
3661                    evalNeeded = true;
3662                    son.accept(this);
3663                    evalNeeded = false;
3664                    value = evalResultValue;
3665                } else if (son instanceof XQueryExpressionSequence && ((XQueryExpressionSequence) son).getSubExpressions().size() == 1) {
3666                    evalNeeded = true;
3667                    XQueryExpression firstSon = (XQueryExpression) ((XQueryExpressionSequence) son).getSubExpressions().get(0);
3668                    firstSon.accept(this);
3669                    evalNeeded = false;
3670                    // // DANGER!!! Olivier: 2002/12/17
3671
// if (firstSon instanceof AttributeValuePair && ((AttributeValuePair) firstSon).isComputed())
3672
// continue;
3673
value = evalResultValue;
3674                } else
3675                    continue;
3676                // test if attribute already exists
3677
// erase LARS 29/06/04
3678
//if (listAttributes.getValue((nameSpaceAtt == null ? "" : nameSpaceAtt), localNameAtt) != null)
3679
// throw new ReconstructionException("An element cannot have several attributes with the same name.");
3680
if (nameSpaceAtt != EMPTY_STRING) {
3681                    String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpaceAtt);
3682                    if (prefix == null) {
3683                        if (declaredDeclarations != null)
3684                            prefix = declaredDeclarations.getPrefix(nameSpaceAtt);
3685                        if (prefix != null)
3686                            reconstructionDeclarations.declarePrefix(prefix, nameSpaceAtt == null ? "" : nameSpaceAtt);
3687                    }
3688                }
3689                // generate attribute
3690
if (listAttributes.getValue((nameSpaceAtt == null ? "" : nameSpaceAtt), localNameAtt) == null)
3691                    listAttributes.addAttribute((nameSpaceAtt == null ? "" : nameSpaceAtt), localNameAtt, "", "STRING", (value == null ? "" : value));
3692            } else {
3693                boolean root = son.getRoot();
3694                if (son instanceof XQueryExpressionSequence) {
3695                    dependIDs = ((XQueryExpression) ((XQueryExpressionSequence) son).getSubExpressions().get(0)).getDependIDs();
3696                    root = ((XQueryExpression) ((XQueryExpressionSequence) son).getSubExpressions().get(0)).getRoot();
3697                }
3698                noNext = false;
3699                boolean changeDependIDs = true;
3700                this.setIdentifiers(false);
3701                QType qtype = son.getQType();
3702                String JavaDoc value = null;
3703
3704                while (!isEmpty(dependIDs) && changeDependIDs) {
3705
3706                    // get nameSpaceAtt, localNameAtt and value from expression
3707
String JavaDoc nameSpaceAtt = ((QName) qtype.getName()).getNameSpace();
3708                    String JavaDoc localNameAtt = ((QName) qtype.getName()).getLocalName();
3709                    if (son instanceof Variable) {
3710                        XQueryExpression expr = ((Variable) son).getExpression();
3711                        if (!noResultSet)
3712                            value = fetch(son.getStringValue(), 0, son.getLoopIDs());
3713                    } else if (son instanceof LocatedExpression) {
3714                        evalNeeded = true;
3715                        son.accept(this);
3716                        evalNeeded = false;
3717                        value = evalResultValue;
3718                    } else if (son instanceof XQueryExpressionSequence && ((XQueryExpressionSequence) son).getSubExpressions().size() == 1) {
3719                        evalNeeded = true;
3720                        ((XQueryExpression) ((XQueryExpressionSequence) son).getSubExpressions().get(0)).accept(this);
3721                        evalNeeded = false;
3722                        value = evalResultValue;
3723                    } else
3724                        continue;
3725                    // test if attribute already exists
3726
if (listAttributes.getValue((nameSpaceAtt == null ? "" : nameSpaceAtt), localNameAtt) != null)
3727                        throw new ReconstructionException("An element cannot have several attributes with the same name.");
3728                    if (nameSpaceAtt != EMPTY_STRING) {
3729                        String JavaDoc prefix = reconstructionDeclarations.getPrefix(nameSpaceAtt);
3730                        if (prefix == null) {
3731                            if (declaredDeclarations != null)
3732                                prefix = declaredDeclarations.getPrefix(nameSpaceAtt);
3733                            if (prefix != null)
3734                                reconstructionDeclarations.declarePrefix(prefix, nameSpaceAtt == null ? "" : nameSpaceAtt);
3735                        }
3736                    }
3737                    // generate attribute
3738
listAttributes.addAttribute((nameSpaceAtt == null ? "" : nameSpaceAtt), localNameAtt, "", "STRING", (value == null ? "" : value));
3739
3740                    this.setIdentifiers(false);
3741                    if (!hasNext())
3742                        break;
3743                    changeDependIDs = changeDependIDs(currentIdentifiers, nextIdentifiers, dependIDs);
3744                    if (!changeDependIDs) {
3745                        noNext = true;
3746                        break;
3747                    }
3748                    if (!noNext) {
3749                        noReconstructor = true;
3750                        if (!hasNext())
3751                            break;
3752                        if (!root)
3753                            identifierCopy(currentIdentifiers, lastIdentifiers);
3754                        nextAsSAX();
3755                        this.setIdentifiers(true);
3756                        changeDependIDs = changeDependIDs(lastIdentifiers, currentIdentifiers, dependIDs);
3757                    }
3758                }
3759            }
3760        }
3761    }
3762
3763}
3764
Popular Tags