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 26 package com.sun.xml.internal.bind.v2.model.impl; 27 28 import java.util.Collections; 29 import java.util.List; 30 31 import javax.xml.bind.annotation.XmlList; 32 33 import com.sun.xml.internal.bind.v2.model.core.ID; 34 import com.sun.xml.internal.bind.v2.model.core.NonElement; 35 import com.sun.xml.internal.bind.v2.model.core.PropertyInfo; 36 import com.sun.xml.internal.bind.v2.model.runtime.RuntimeNonElementRef; 37 import com.sun.xml.internal.bind.v2.model.runtime.RuntimePropertyInfo; 38 import com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationException; 39 import com.sun.xml.internal.bind.v2.runtime.Transducer; 40 import com.sun.xml.internal.bind.v2.runtime.reflect.Accessor; 41 42 /** 43 * {@link PropertyInfoImpl} that can only have one type. 44 * 45 * Specifically, {@link AttributePropertyInfoImpl} and {@link ValuePropertyInfoImpl}. 46 * 47 * @author Kohsuke Kawaguchi 48 */ 49 abstract class SingleTypePropertyInfoImpl<T,C,F,M> 50 extends PropertyInfoImpl<T,C,F,M> { 51 52 /** 53 * Computed lazily. 54 * 55 * @see {@link #getTarget()}. 56 */ 57 private NonElement<T,C> type; 58 59 public SingleTypePropertyInfoImpl(ClassInfoImpl<T,C,F,M> classInfo, PropertySeed<T,C,F,M> seed) { 60 super(classInfo, seed); 61 if(this instanceof RuntimePropertyInfo) { 62 Accessor rawAcc = ((RuntimeClassInfoImpl.RuntimePropertySeed)seed).getAccessor(); 63 if(getAdapter()!=null && !isCollection()) 64 // adapter for a single-value property is handled by accessor. 65 // adapter for a collection property is handled by lister. 66 rawAcc = rawAcc.adapt(((RuntimePropertyInfo)this).getAdapter()); 67 this.acc = rawAcc; 68 } else 69 this.acc = null; 70 } 71 72 public List<? extends NonElement<T,C>> ref() { 73 return Collections.singletonList(getTarget()); 74 } 75 76 public NonElement<T,C> getTarget() { 77 if(type==null) { 78 assert parent.builder!=null : "this method must be called during the build stage"; 79 type = parent.builder.getTypeInfo(getIndividualType(),this); 80 } 81 return type; 82 } 83 84 public PropertyInfo<T,C> getSource() { 85 return this; 86 } 87 88 public void link() { 89 super.link(); 90 91 if (!(NonElement.ANYTYPE_NAME.equals(type.getTypeName()) || type.isSimpleType() || id()==ID.IDREF)) { 92 parent.builder.reportError(new IllegalAnnotationException( 93 Messages.SIMPLE_TYPE_IS_REQUIRED.format(), 94 seed 95 )); 96 } 97 98 if(!isCollection() && seed.hasAnnotation(XmlList.class)) { 99 parent.builder.reportError(new IllegalAnnotationException( 100 Messages.XMLLIST_ON_SINGLE_PROPERTY.format(), this 101 )); 102 } 103 } 104 105 // 106 // 107 // technically these code belong to runtime implementation, but moving the code up here 108 // allows this to be shared between RuntimeValuePropertyInfoImpl and RuntimeAttributePropertyInfoImpl 109 // 110 // 111 112 private final Accessor acc; 113 /** 114 * Lazily created. 115 */ 116 private Transducer xducer; 117 118 public Accessor getAccessor() { 119 return acc; 120 } 121 122 123 public Transducer getTransducer() { 124 if(xducer==null) { 125 xducer = RuntimeModelBuilder.createTransducer((RuntimeNonElementRef)this); 126 if(xducer==null) { 127 // this situation is checked by by the link method. 128 // avoid repeating the same error by silently recovering 129 xducer = RuntimeBuiltinLeafInfoImpl.STRING; 130 } 131 } 132 return xducer; 133 } 134 }