1/* 2 * Copyright (c) 1997, 2012, 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 */ 25 26package com.sun.xml.internal.bind.v2.model.impl; 27 28import java.io.IOException; 29import java.lang.reflect.Field; 30import java.lang.reflect.Method; 31import java.lang.reflect.Type; 32import java.util.EnumMap; 33import java.util.HashMap; 34import java.util.Map; 35 36import javax.xml.namespace.QName; 37import javax.xml.stream.XMLStreamException; 38 39import com.sun.xml.internal.bind.api.AccessorException; 40import com.sun.xml.internal.bind.v2.model.annotation.FieldLocatable; 41import com.sun.xml.internal.bind.v2.model.annotation.Locatable; 42import com.sun.xml.internal.bind.v2.model.runtime.RuntimeEnumLeafInfo; 43import com.sun.xml.internal.bind.v2.model.runtime.RuntimeNonElement; 44import com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationException; 45import com.sun.xml.internal.bind.v2.runtime.Name; 46import com.sun.xml.internal.bind.v2.runtime.Transducer; 47import com.sun.xml.internal.bind.v2.runtime.XMLSerializer; 48 49import org.xml.sax.SAXException; 50 51/** 52 * @author Kohsuke Kawaguchi 53 */ 54final class RuntimeEnumLeafInfoImpl<T extends Enum<T>,B> extends EnumLeafInfoImpl<Type,Class,Field,Method> 55 implements RuntimeEnumLeafInfo, Transducer<T> { 56 57 public Transducer<T> getTransducer() { 58 return this; 59 } 60 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; 66 67 private final Map<B,T> parseMap = new HashMap<B,T>(); 68 private final Map<T,B> printMap; 69 70 RuntimeEnumLeafInfoImpl(RuntimeModelBuilder builder, Locatable upstream, Class<T> enumType) { 71 super(builder,upstream,enumType,enumType); 72 this.printMap = new EnumMap<T,B>(enumType); 73 74 baseXducer = ((RuntimeNonElement)baseType).getTransducer(); 75 } 76 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 } 93 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 } 102 103 parseMap.put(b,t); 104 printMap.put(t,b); 105 106 return new RuntimeEnumConstantImpl(this, name, literal, last); 107 } 108 109 public QName[] getTypeNames() { 110 return new QName[]{getTypeName()}; 111 } 112 113 public boolean isDefault() { 114 return false; 115 } 116 117 @Override 118 public Class getClazz() { 119 return clazz; 120 } 121 122 public boolean useNamespace() { 123 return baseXducer.useNamespace(); 124 } 125 126 public void declareNamespace(T t, XMLSerializer w) throws AccessorException { 127 baseXducer.declareNamespace(printMap.get(t),w); 128 } 129 130 public CharSequence print(T t) throws AccessorException { 131 return baseXducer.print(printMap.get(t)); 132 } 133 134 public T parse(CharSequence lexical) throws AccessorException, SAXException { 135 // TODO: error handling 136 137 B b = baseXducer.parse(lexical); 138 139 if (tokenStringType) { 140 b = (B) ((String)b).trim(); 141 } 142 143 return parseMap.get(b); 144 } 145 146 public void writeText(XMLSerializer w, T t, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException { 147 baseXducer.writeText(w,printMap.get(t),fieldName); 148 } 149 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 } 153 154 public QName getTypeName(T instance) { 155 return null; 156 } 157} 158