Fri, 22 Nov 2013 21:11:19 +0100
8010935: Better XML handling
8027378: Two closed/javax/xml/8005432 fails with jdk7u51b04
8028382: Two javax/xml/8005433 tests still fail after the fix JDK-8028147
Summary: base fix + fixes for test regressions; fix also reviewed by Maxim Soloviev, Alexander Fomin
Reviewed-by: mchung, mgrebac, mullan
1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.bind.v2.model.impl;
28 import java.io.IOException;
29 import java.lang.reflect.Field;
30 import java.lang.reflect.Method;
31 import java.lang.reflect.Type;
32 import java.util.EnumMap;
33 import java.util.HashMap;
34 import java.util.Map;
36 import javax.xml.namespace.QName;
37 import javax.xml.stream.XMLStreamException;
39 import com.sun.xml.internal.bind.api.AccessorException;
40 import com.sun.xml.internal.bind.v2.model.annotation.FieldLocatable;
41 import com.sun.xml.internal.bind.v2.model.annotation.Locatable;
42 import com.sun.xml.internal.bind.v2.model.runtime.RuntimeEnumLeafInfo;
43 import com.sun.xml.internal.bind.v2.model.runtime.RuntimeNonElement;
44 import com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationException;
45 import com.sun.xml.internal.bind.v2.runtime.Name;
46 import com.sun.xml.internal.bind.v2.runtime.Transducer;
47 import com.sun.xml.internal.bind.v2.runtime.XMLSerializer;
49 import org.xml.sax.SAXException;
51 /**
52 * @author Kohsuke Kawaguchi
53 */
54 final class RuntimeEnumLeafInfoImpl<T extends Enum<T>,B> extends EnumLeafInfoImpl<Type,Class,Field,Method>
55 implements RuntimeEnumLeafInfo, Transducer<T> {
57 public Transducer<T> getTransducer() {
58 return this;
59 }
61 /**
62 * {@link Transducer} that knows how to convert a lexical value
63 * into the Java value that we can handle.
64 */
65 private final Transducer<B> baseXducer;
67 private final Map<B,T> parseMap = new HashMap<B,T>();
68 private final Map<T,B> printMap;
70 RuntimeEnumLeafInfoImpl(RuntimeModelBuilder builder, Locatable upstream, Class<T> enumType) {
71 super(builder,upstream,enumType,enumType);
72 this.printMap = new EnumMap<T,B>(enumType);
74 baseXducer = ((RuntimeNonElement)baseType).getTransducer();
75 }
77 @Override
78 public RuntimeEnumConstantImpl createEnumConstant(String name, String literal, Field constant, EnumConstantImpl<Type,Class,Field,Method> last) {
79 T t;
80 try {
81 try {
82 constant.setAccessible(true);
83 } catch (SecurityException e) {
84 // in case the constant is already accessible, swallow this error.
85 // if the constant is indeed not accessible, we will get IllegalAccessException
86 // in the following line, and that is not too late.
87 }
88 t = (T)constant.get(null);
89 } catch (IllegalAccessException e) {
90 // impossible, because this is an enum constant
91 throw new IllegalAccessError(e.getMessage());
92 }
94 B b = null;
95 try {
96 b = baseXducer.parse(literal);
97 } catch (Exception e) {
98 builder.reportError(new IllegalAnnotationException(
99 Messages.INVALID_XML_ENUM_VALUE.format(literal,baseType.getType().toString()), e,
100 new FieldLocatable<Field>(this,constant,nav()) ));
101 }
103 parseMap.put(b,t);
104 printMap.put(t,b);
106 return new RuntimeEnumConstantImpl(this, name, literal, last);
107 }
109 public QName[] getTypeNames() {
110 return new QName[]{getTypeName()};
111 }
113 public boolean isDefault() {
114 return false;
115 }
117 @Override
118 public Class getClazz() {
119 return clazz;
120 }
122 public boolean useNamespace() {
123 return baseXducer.useNamespace();
124 }
126 public void declareNamespace(T t, XMLSerializer w) throws AccessorException {
127 baseXducer.declareNamespace(printMap.get(t),w);
128 }
130 public CharSequence print(T t) throws AccessorException {
131 return baseXducer.print(printMap.get(t));
132 }
134 public T parse(CharSequence lexical) throws AccessorException, SAXException {
135 // TODO: error handling
137 B b = baseXducer.parse(lexical);
139 if (tokenStringType) {
140 b = (B) ((String)b).trim();
141 }
143 return parseMap.get(b);
144 }
146 public void writeText(XMLSerializer w, T t, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
147 baseXducer.writeText(w,printMap.get(t),fieldName);
148 }
150 public void writeLeafElement(XMLSerializer w, Name tagName, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
151 baseXducer.writeLeafElement(w,tagName,printMap.get(o),fieldName);
152 }
154 public QName getTypeName(T instance) {
155 return null;
156 }
157 }