Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import unknow.server.http.test.xml.Complex;
import unknow.server.jaxb.ContextFactory;

public class BenchJaxb {
private static final ClassLoader cl = BenchJaxb.class.getClassLoader();
Expand All @@ -23,7 +24,7 @@ public class BenchJaxb {

static {
try {
UNKNOW = new unknow.server.http.test.generated.JaxbContextFactory().createContext(CLASS, null);
UNKNOW = new ContextFactory().createContext(CLASS, null);
JAXB = new org.glassfish.jaxb.runtime.v2.JAXBContextFactory().createContext(CLASS, null);
MOXY = new org.eclipse.persistence.jaxb.XMLBindingContextFactory().createContext(CLASS, null);
} catch (JAXBException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
/**
* @author unknow
*/
public class Context extends JAXBContext {
public final class Context extends JAXBContext {

private final Map<QName, XmlRootHandler<?>> rootElements;
private final Map<Class<?>, XmlRootHandler<?>> rootHandlers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

import javax.xml.namespace.QName;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBContextFactory;
import jakarta.xml.bind.JAXBException;
Expand All @@ -29,23 +36,62 @@
/**
* @author unknow
*/
public abstract class ContextFactory implements JAXBContextFactory {
private final Map<Class<?>, XmlHandler<?>> handlers = new HashMap<>();
public final class ContextFactory implements JAXBContextFactory {
private static final Logger logger = LoggerFactory.getLogger(ContextFactory.class);

private static final Map<Class<?>, XmlHandler<?>> handlers = new HashMap<>();
private static final Map<String, Collection<Class<?>>> classes = new HashMap<>();

static {
handlers.put(BigDecimal.class, BigDecimalHandler.INSTANCE);
handlers.put(BigInteger.class, BigIntegerHandler.INSTANCE);
handlers.put(String.class, StringHandler.INSTANCE);
handlers.put(boolean.class, BooleanHandler.INSTANCE);
handlers.put(Boolean.class, BooleanHandler.INSTANCE);
handlers.put(byte.class, ByteHandler.INSTANCE);
handlers.put(Byte.class, ByteHandler.INSTANCE);
handlers.put(short.class, ShortHandler.INSTANCE);
handlers.put(Short.class, ShortHandler.INSTANCE);
handlers.put(char.class, CharHandler.INSTANCE);
handlers.put(Character.class, CharHandler.INSTANCE);
handlers.put(int.class, IntHandler.INSTANCE);
handlers.put(Integer.class, IntHandler.INSTANCE);
handlers.put(long.class, LongHandler.INSTANCE);
handlers.put(Long.class, LongHandler.INSTANCE);
handlers.put(float.class, FloatHandler.INSTANCE);
handlers.put(Float.class, FloatHandler.INSTANCE);
handlers.put(double.class, DoubleHandler.INSTANCE);
handlers.put(Double.class, DoubleHandler.INSTANCE);

protected <T> void register(Class<T> cl, XmlHandler<T> h) {
handlers.put(cl, h);
for (XmlHandlerLoader l : ServiceLoader.load(XmlHandlerLoader.class)) {
String contextPath = l.contextPath();
if (classes.containsKey(contextPath))
logger.warn("Duplicate context {}", contextPath);
Collection<XmlHandler<?>> list = l.handlers();
Class<?>[] c = new Class[list.size()];
int i = 0;
for (XmlHandler<?> h : list) {
if (handlers.containsKey(h.clazz()))
logger.warn("Duplicate handled {}", h);
c[i++] = h.clazz();
handlers.put(h.clazz(), h);
}
classes.put(contextPath, Arrays.asList(c));
}
}

@Override
public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException {
return createContext(Arrays.asList(classesToBeBound));
}

private JAXBContext createContext(Collection<Class<?>> classesToBeBound) throws JAXBException {
Map<Class<?>, XmlHandler<?>> h = new HashMap<>();
Map<Class<?>, XmlRootHandler<?>> rh = new HashMap<>();
Map<QName, XmlRootHandler<?>> re = new HashMap<>();

for (Class<?> c : classesToBeBound) {
XmlHandler<?> x = handlers.get(c);
if (x == null)
x = defaultHandler(c);
if (x == null)
throw new JAXBException("No handler for class " + c);
if (x instanceof XmlRootHandler) {
Expand All @@ -58,55 +104,17 @@ public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> pro
return new Context(re, rh, h);
}

private final XmlHandler<?> defaultHandler(Class<?> cl) {
if (BigDecimal.class == cl)
return BigDecimalHandler.INSTANCE;
if (BigInteger.class == cl)
return BigIntegerHandler.INSTANCE;
if (String.class == cl)
return StringHandler.INSTANCE;
if (boolean.class == cl || Boolean.class == cl)
return BooleanHandler.INSTANCE;
if (byte.class == cl || Byte.class == cl)
return ByteHandler.INSTANCE;
if (short.class == cl || Short.class == cl)
return ShortHandler.INSTANCE;
if (char.class == cl || Character.class == cl)
return CharHandler.INSTANCE;
if (int.class == cl || Integer.class == cl)
return IntHandler.INSTANCE;
if (long.class == cl || Long.class == cl)
return LongHandler.INSTANCE;
if (float.class == cl || Float.class == cl)
return FloatHandler.INSTANCE;
if (double.class == cl || Double.class == cl)
return DoubleHandler.INSTANCE;
return null;
}

protected abstract Collection<Class<?>> getClasses(String contextPackage);

@Override
public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException {
Map<Class<?>, XmlHandler<?>> h = new HashMap<>();
Map<Class<?>, XmlRootHandler<?>> rh = new HashMap<>();
Map<QName, XmlRootHandler<?>> re = new HashMap<>();

List<Class<?>> list = new ArrayList<>();
for (String s : contextPath.split(":")) {
for (Class<?> c : getClasses(s)) {
XmlHandler<?> x = handlers.get(c);
if (x == null)
throw new JAXBException("No handler for class " + c);
if (x instanceof XmlRootHandler) {
XmlRootHandler<?> r = (XmlRootHandler<?>) x;
re.put(r.qname(), r);
rh.put(c, r);
}
h.put(c, x);
}
Collection<Class<?>> a = classes.get(s);
if (a == null)
throw new JAXBException("No classes mapped in context " + s);
list.addAll(a);
}

return new Context(re, rh, h);
return createContext(list);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ protected void beforeEndElement() {
if (depth > 0 && stack[depth] == WROTE_MARKUP) { // but not data
try {
writeNewLine(depth - 1);
} catch (Exception ignored) { // ok
} catch (@SuppressWarnings("unused") Exception e) { // ok
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
* @param <T> xmlElement
*/
public interface XmlHandler<T> {
/**
* @return mapped class
*/
Class<T> clazz();

/**
* write object content
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package unknow.server.jaxb;

import java.util.Collection;

public interface XmlHandlerLoader {
/**
* @return the linked context path
*/
String contextPath();

/**
* @return the mapped class
*/
Collection<XmlHandler<?>> handlers();

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public class BigDecimalHandler implements XmlSimpleHandler<BigDecimal> {
private BigDecimalHandler() {
}

@Override
public Class<BigDecimal> clazz() {
return BigDecimal.class;
}

@Override
public String toString(BigDecimal t) {
return t.toString();
Expand All @@ -27,4 +32,5 @@ public String toString(BigDecimal t) {
public BigDecimal toObject(String s) throws JAXBException {
return new BigDecimal(s);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public class BigIntegerHandler implements XmlSimpleHandler<BigInteger> {
private BigIntegerHandler() {
}

@Override
public Class<BigInteger> clazz() {
return BigInteger.class;
}

@Override
public String toString(BigInteger t) {
return t.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public class BooleanHandler implements XmlSimpleHandler<Boolean> {
private BooleanHandler() {
}

@Override
public Class<Boolean> clazz() {
return Boolean.class;
}

@Override
public String toString(Boolean t) {
return Boolean.toString(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public class ByteHandler implements XmlSimpleHandler<Byte> {
private ByteHandler() {
}

@Override
public Class<Byte> clazz() {
return Byte.class;
}

@Override
public String toString(Byte t) {
return Byte.toString(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public class CharHandler implements XmlSimpleHandler<Character> {
private CharHandler() {
}

@Override
public Class<Character> clazz() {
return Character.class;
}

@Override
public String toString(Character t) {
return Character.toString(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public class DoubleHandler implements XmlSimpleHandler<Double> {
private DoubleHandler() {
}

@Override
public Class<Double> clazz() {
return Double.class;
}

@Override
public String toString(Double t) {
return Double.toString(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ public class DurationHandler implements XmlSimpleHandler<Duration> {
private DurationHandler() {
}

@Override
public Class<Duration> clazz() {
return Duration.class;
}

@Override
public String toString(Duration t) {
return t.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public class FloatHandler implements XmlSimpleHandler<Float> {
private FloatHandler() {
}

@Override
public Class<Float> clazz() {
return Float.class;
}

@Override
public String toString(Float t) {
return Float.toString(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public class IntHandler implements XmlSimpleHandler<Integer> {
private IntHandler() {
}

@Override
public Class<Integer> clazz() {
return Integer.class;
}

@Override
public String toString(Integer t) {
return Integer.toString(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public class LocalDateHandler implements XmlSimpleHandler<LocalDate> {
private LocalDateHandler() {
}

@Override
public Class<LocalDate> clazz() {
return LocalDate.class;
}

@Override
public String toString(LocalDate t) {
return t.format(FMT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public class LocalDateTimeHandler implements XmlSimpleHandler<LocalDateTime> {
private LocalDateTimeHandler() {
}

@Override
public Class<LocalDateTime> clazz() {
return LocalDateTime.class;
}

@Override
public String toString(LocalDateTime t) {
return t.format(FMT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public class LocalTimeHandler implements XmlSimpleHandler<LocalTime> {
private LocalTimeHandler() {
}

@Override
public Class<LocalTime> clazz() {
return LocalTime.class;
}

@Override
public String toString(LocalTime t) {
return t.format(FMT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public class LongHandler implements XmlSimpleHandler<Long> {
private LongHandler() {
}

@Override
public Class<Long> clazz() {
return Long.class;
}

@Override
public String toString(Long t) {
return Long.toString(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public class OffsetDateTimeHandler implements XmlSimpleHandler<OffsetDateTime> {
private OffsetDateTimeHandler() {
}

@Override
public Class<OffsetDateTime> clazz() {
return OffsetDateTime.class;
}

@Override
public String toString(OffsetDateTime t) {
return t.format(FMT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ public class PeriodHandler implements XmlSimpleHandler<Period> {
private PeriodHandler() {
}

@Override
public Class<Period> clazz() {
return Period.class;
}

@Override
public String toString(Period t) {
return t.toString();
Expand Down
Loading