use of org.apache.cxf.staxutils.W3CNamespaceContext in project cxf by apache.
the class JAXBEncoderDecoder method findExtraNamespaces.
private static XMLStreamReader findExtraNamespaces(XMLStreamReader source) {
// due to a deficiency in the Stax API, there isn't a way to get all
// the namespace prefixes that are "valid" at this point. Thus, JAXB
// cannot set all the prefixes into the validator (which also doesn't allow
// setting a NSContext, just allows declaring of prefixes) so resolving
// prefixes and such will fail if they were declared on any of the parent
// elements.
//
// We'll use some reflection to grab the known namespaces from woodstox
// or the xerces parser and fake extra namespace decls on the root elements.
// slight performance penalty, but there already is a penalty if you are validating
// anyway.
NamespaceContext c = source.getNamespaceContext();
final Map<String, String> nsMap = new TreeMap<String, String>();
try {
if (c instanceof W3CNamespaceContext) {
Element element = ((W3CNamespaceContext) c).getElement();
while (element != null) {
NamedNodeMap namedNodeMap = element.getAttributes();
for (int i = 0; i < namedNodeMap.getLength(); i++) {
Attr attr = (Attr) namedNodeMap.item(i);
if (attr.getPrefix() != null && attr.getPrefix().equals("xmlns")) {
nsMap.put(attr.getLocalName(), attr.getValue());
}
}
element = (Element) element.getParentNode();
}
} else {
try {
// Woodstox version
c = (NamespaceContext) c.getClass().getMethod("createNonTransientNsContext", Location.class).invoke(c, new Object[1]);
} catch (Throwable t) {
// ignore
}
Field f = ReflectionUtil.getDeclaredField(c.getClass(), "mNamespaces");
ReflectionUtil.setAccessible(f);
String[] ns = (String[]) f.get(c);
for (int x = 0; x < ns.length; x += 2) {
if (ns[x] == null) {
nsMap.put("", ns[x + 1]);
} else {
nsMap.put(ns[x], ns[x + 1]);
}
}
}
} catch (Throwable t) {
// internal JDK/xerces version
try {
Field f = ReflectionUtil.getDeclaredField(c.getClass(), "fNamespaceContext");
ReflectionUtil.setAccessible(f);
Object c2 = f.get(c);
Enumeration<?> enm = (Enumeration<?>) c2.getClass().getMethod("getAllPrefixes").invoke(c2);
while (enm.hasMoreElements()) {
String s = (String) enm.nextElement();
if (s == null) {
nsMap.put("", c.getNamespaceURI(null));
} else {
nsMap.put(s, c.getNamespaceURI(s));
}
}
} catch (Throwable t2) {
// ignore
}
}
if (!nsMap.isEmpty()) {
for (int x = 0; x < source.getNamespaceCount(); x++) {
String pfx = source.getNamespacePrefix(x);
if (pfx == null) {
nsMap.remove("");
} else {
nsMap.remove(pfx);
}
}
if (!nsMap.isEmpty()) {
@SuppressWarnings("unchecked") final Map.Entry<String, String>[] namespaces = nsMap.entrySet().toArray(new Map.Entry[nsMap.size()]);
// OK. we have extra namespaces. We'll need to wrapper the reader
// with a new one that will fake extra namespace events
source = new DepthXMLStreamReader(source) {
public int getNamespaceCount() {
if (getDepth() == 0 && isStartElement()) {
return super.getNamespaceCount() + nsMap.size();
}
return super.getNamespaceCount();
}
public String getNamespacePrefix(int arg0) {
if (getDepth() == 0 && isStartElement()) {
int i = super.getNamespaceCount();
if (arg0 >= i) {
arg0 -= i;
return namespaces[arg0].getKey();
}
}
return super.getNamespacePrefix(arg0);
}
public String getNamespaceURI(int arg0) {
if (getDepth() == 0 && isStartElement()) {
int i = super.getNamespaceCount();
if (arg0 >= i) {
arg0 -= i;
return namespaces[arg0].getValue();
}
}
return super.getNamespaceURI(arg0);
}
};
}
}
return source;
}
use of org.apache.cxf.staxutils.W3CNamespaceContext in project cxf by apache.
the class JAXBDataBinding method addBindingFiles.
private void addBindingFiles(Options opts, List<InputSource> jaxbBindings, SchemaCollection schemas) {
for (InputSource binding : jaxbBindings) {
XMLStreamReader r = StaxUtils.createXMLStreamReader(binding);
try {
StaxUtils.toNextTag(r);
String s = r.getAttributeValue(null, "schemaLocation");
if (StringUtils.isEmpty(s)) {
Document d = StaxUtils.read(r);
XPath p = XPathFactory.newInstance().newXPath();
p.setNamespaceContext(new W3CNamespaceContext(d.getDocumentElement()));
XPathExpression xpe = p.compile(d.getDocumentElement().getAttribute("node"));
for (XmlSchema schema : schemas.getXmlSchemas()) {
if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(schema.getTargetNamespace())) {
continue;
}
Object src = getSchemaNode(schema, schemas);
NodeList nodes = (NodeList) xpe.evaluate(src, XPathConstants.NODESET);
if (nodes.getLength() > 0) {
String key = schema.getSourceURI();
binding = convertToTmpInputSource(d.getDocumentElement(), key);
opts.addBindFile(binding);
binding = null;
}
}
}
} catch (Exception ex) {
// ignore, just pass to jaxb
} finally {
try {
r.close();
} catch (Exception ex) {
// ignore
}
}
if (binding != null) {
opts.addBindFile(binding);
}
}
}
use of org.apache.cxf.staxutils.W3CNamespaceContext in project cxf by apache.
the class ClientServerRPCLitTest method testDispatchClient.
@Test
public void testDispatchClient() throws Exception {
SOAPServiceRPCLit service = new SOAPServiceRPCLit();
Dispatch<Source> disp = service.createDispatch(portName, Source.class, javax.xml.ws.Service.Mode.PAYLOAD);
updateAddressPort(disp, PORT);
String req = "<ns1:sendReceiveData xmlns:ns1=\"http://apache.org/hello_world_rpclit\">" + "<in xmlns:ns2=\"http://apache.org/hello_world_rpclit/types\">" + "<ns2:elem1>elem1</ns2:elem1><ns2:elem2>elem2</ns2:elem2><ns2:elem3>45</ns2:elem3>" + "</in></ns1:sendReceiveData>";
Source source = new StreamSource(new StringReader(req));
Source resp = disp.invoke(source);
assertNotNull(resp);
Node nd = StaxUtils.read(resp);
if (nd instanceof Document) {
nd = ((Document) nd).getDocumentElement();
}
XPathUtils xpu = new XPathUtils(new W3CNamespaceContext((Element) nd));
assertTrue(xpu.isExist("/ns1:sendReceiveDataResponse/out", nd, XPathConstants.NODE));
}
use of org.apache.cxf.staxutils.W3CNamespaceContext in project cxf by apache.
the class SAAJStreamWriter method getPrefix.
@Override
public String getPrefix(String nsuri) throws XMLStreamException {
if (isOverlaid && part != null && getCurrentNode() == null) {
Node nd = part.getFirstChild();
while (nd != null) {
if (nd instanceof Element) {
Iterator<String> it = new W3CNamespaceContext((Element) nd).getPrefixes(nsuri);
if (it.hasNext()) {
return it.next();
}
nd = null;
} else {
nd = nd.getNextSibling();
}
}
}
return super.getPrefix(nsuri);
}
Aggregations