blob: ba64c5e26fb728f0e68ea88eec5b27e74d7426d3 [file] [log] [blame]
/* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.xmlbeans.impl.xpath.saxon;
import org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.store.Cur;
import org.apache.xmlbeans.impl.store.DomImpl;
import org.apache.xmlbeans.impl.store.Locale;
import org.apache.xmlbeans.impl.xpath.XPathEngine;
import org.apache.xmlbeans.impl.xpath.XPathExecutionContext;
import org.w3c.dom.Node;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.List;
public class SaxonXPathEngine extends XPathExecutionContext implements XPathEngine {
// full datetime format: yyyy-MM-dd'T'HH:mm:ss'Z'
private final DateFormat xmlDateFormat = new SimpleDateFormat("yyyy-MM-dd");
private Cur _cur;
private SaxonXPath _engine;
private boolean _firstCall = true;
private final long _version;
SaxonXPathEngine(SaxonXPath xpathImpl, Cur c) {
_engine = xpathImpl;
_version = c.getLocale().version();
_cur = c.weakCur(this);
}
public boolean next(Cur c) {
if (!_firstCall) {
return false;
}
_firstCall = false;
if (_cur != null && _version != _cur.getLocale().version()) {
throw new ConcurrentModificationException("Document changed during select");
}
List resultsList = _engine.selectPath(_cur.getDom());
int i;
for (i = 0; i < resultsList.size(); i++) {
//simple type function results
Object node = resultsList.get(i);
Cur pos = null;
if (!(node instanceof Node)) {
Object obj = resultsList.get(i);
String value;
if (obj instanceof Date) {
value = xmlDateFormat.format((Date) obj);
} else if (obj instanceof BigDecimal) {
value = ((BigDecimal) obj).toPlainString();
} else {
value = obj.toString();
}
//we cannot leave the cursor's locale, as
//everything is done in the selections of this cursor
org.apache.xmlbeans.impl.store.Locale l = c.getLocale();
try {
pos = l.load("<xml-fragment/>").tempCur();
pos.setValue(value);
SchemaType type = getType(node);
Locale.autoTypeDocument(pos, type, null);
//move the cur to the actual text
pos.next();
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
assert (node instanceof DomImpl.Dom) :
"New object created in XPATH!";
pos = ((DomImpl.Dom) node).tempCur();
}
c.addToSelection(pos);
pos.release();
}
release();
_engine = null;
return true;
}
private SchemaType getType(Object node) {
SchemaType type;
if (node instanceof Integer) {
type = XmlInteger.type;
} else if (node instanceof Double) {
type = XmlDouble.type;
} else if (node instanceof Long) {
type = XmlLong.type;
} else if (node instanceof Float) {
type = XmlFloat.type;
} else if (node instanceof BigDecimal) {
type = XmlDecimal.type;
} else if (node instanceof Boolean) {
type = XmlBoolean.type;
} else if (node instanceof String) {
type = XmlString.type;
} else if (node instanceof Date) {
type = XmlDate.type;
} else {
type = XmlAnySimpleType.type;
}
return type;
}
public void release() {
if (_cur != null) {
_cur.release();
_cur = null;
}
}
}