org.apache.cxf.jaxrs.provider.aegis.AegisJSONProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-bundle-minimal Show documentation
Show all versions of cxf-bundle-minimal Show documentation
Apache CXF Minimal Bundle Jar
The newest version!
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.cxf.jaxrs.provider.aegis;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.w3c.dom.Document;
import org.apache.cxf.aegis.AegisContext;
import org.apache.cxf.aegis.AegisWriter;
import org.apache.cxf.aegis.type.AegisType;
import org.apache.cxf.jaxrs.provider.json.utils.JSONUtils;
import org.apache.cxf.jaxrs.provider.json.utils.PrefixCollectingXMLStreamWriter;
import org.apache.cxf.jaxrs.utils.ExceptionUtils;
import org.apache.cxf.jaxrs.utils.HttpUtils;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.cxf.staxutils.W3CDOMStreamWriter;
import org.codehaus.jettison.mapped.Configuration;
@Provider
@Produces({"application/json" })
@Consumes({"application/json" })
public final class AegisJSONProvider extends AegisElementProvider {
private List arrayKeys;
private boolean serializeAsArray;
private boolean dropRootElement;
private boolean ignoreNamespaces;
private ConcurrentHashMap namespaceMap = new ConcurrentHashMap();
public AegisJSONProvider() {
}
public void setIgnoreNamespaces(boolean ignoreNamespaces) {
this.ignoreNamespaces = ignoreNamespaces;
}
public void setDropRootElement(boolean dropRootElement) {
this.dropRootElement = dropRootElement;
}
public void setArrayKeys(List keys) {
this.arrayKeys = keys;
}
public void setSerializeAsArray(boolean asArray) {
this.serializeAsArray = asArray;
}
@Override
public boolean isReadable(Class> type, Type genericType, Annotation[] annotations, MediaType mt) {
return true;
}
public void setNamespaceMap(Map nsMap) {
this.namespaceMap = new ConcurrentHashMap(nsMap);
}
@Override
public void writeTo(T obj, Class> type, Type genericType, Annotation[] anns, MediaType m,
MultivaluedMap headers, OutputStream os) throws IOException {
if (type == null) {
type = obj.getClass();
}
if (genericType == null) {
genericType = type;
}
AegisContext context = getAegisContext(type, genericType);
AegisType aegisType = context.getTypeMapping().getType(genericType);
AegisWriter aegisWriter = context.createXMLStreamWriter();
try {
W3CDOMStreamWriter w3cStreamWriter = new W3CDOMStreamWriter();
XMLStreamWriter spyingWriter = new PrefixCollectingXMLStreamWriter(w3cStreamWriter,
namespaceMap);
spyingWriter.writeStartDocument();
// use type qname as element qname?
aegisWriter.write(obj, aegisType.getSchemaType(), false, spyingWriter, aegisType);
spyingWriter.writeEndDocument();
spyingWriter.close();
Document dom = w3cStreamWriter.getDocument();
// ok, now the namespace map has all the prefixes.
String enc = HttpUtils.getSetEncoding(m, headers, "UTF-8");
XMLStreamWriter xmlStreamWriter = createStreamWriter(aegisType.getSchemaType(), enc, os);
xmlStreamWriter.writeStartDocument();
StaxUtils.copy(dom, xmlStreamWriter);
// Jettison needs, and StaxUtils.copy doesn't do it.
xmlStreamWriter.writeEndDocument();
xmlStreamWriter.flush();
xmlStreamWriter.close();
} catch (Exception e) {
throw ExceptionUtils.toInternalServerErrorException(e, null);
}
}
@Override
protected XMLStreamWriter createStreamWriter(QName typeQName, String enc, OutputStream os) throws Exception {
Configuration config =
JSONUtils.createConfiguration(namespaceMap,
writeXsiType && !ignoreNamespaces, false, null);
XMLStreamWriter writer = JSONUtils.createStreamWriter(os, typeQName,
writeXsiType && !ignoreNamespaces, config, serializeAsArray, arrayKeys, dropRootElement, enc);
return JSONUtils.createIgnoreNsWriterIfNeeded(writer, ignoreNamespaces, !writeXsiType);
}
@Override
protected XMLStreamReader createStreamReader(AegisType typeToRead, InputStream is) throws Exception {
// the namespace map. Oh, the namespace map.
// This is wrong, but might make unit tests pass until we redesign.
if (typeToRead != null) {
String pfx = "ns1";
int count = 1;
while (namespaceMap.containsValue(pfx)) {
count++;
pfx = "ns" + count;
}
namespaceMap.putIfAbsent(typeToRead.getSchemaType().getNamespaceURI(), pfx);
}
return JSONUtils.createStreamReader(is, readXsiType, namespaceMap);
}
}