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.util.LinkedHashSet; 29import java.util.Set; 30 31import javax.xml.bind.annotation.XmlElementDecl; 32 33import com.sun.xml.internal.bind.v2.model.annotation.Locatable; 34import com.sun.xml.internal.bind.v2.model.annotation.MethodLocatable; 35import com.sun.xml.internal.bind.v2.model.core.RegistryInfo; 36import com.sun.xml.internal.bind.v2.model.core.TypeInfo; 37import com.sun.xml.internal.bind.v2.model.nav.Navigator; 38import com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationException; 39import com.sun.xml.internal.bind.v2.runtime.Location; 40import com.sun.xml.internal.bind.v2.ContextFactory; 41 42/** 43 * Implementation of {@link RegistryInfo}. 44 * 45 * @author Kohsuke Kawaguchi 46 */ 47// experimenting with shorter type parameters for <T,C,F,M> quadruple. 48// the idea is that they show so often that you'd understand the meaning 49// without relying on the whole name. 50final class RegistryInfoImpl<T,C,F,M> implements Locatable, RegistryInfo<T,C> { 51 52 final C registryClass; 53 private final Locatable upstream; 54 private final Navigator<T,C,F,M> nav; 55 56 /** 57 * Types that are referenced from this registry. 58 */ 59 private final Set<TypeInfo<T,C>> references = new LinkedHashSet<TypeInfo<T,C>>(); 60 61 /** 62 * Picks up references in this registry to other types. 63 */ 64 RegistryInfoImpl(ModelBuilder<T,C,F,M> builder, Locatable upstream, C registryClass) { 65 this.nav = builder.nav; 66 this.registryClass = registryClass; 67 this.upstream = upstream; 68 builder.registries.put(getPackageName(),this); 69 70 if(nav.getDeclaredField(registryClass,ContextFactory.USE_JAXB_PROPERTIES)!=null) { 71 // the user is trying to use ObjectFactory that we generate for interfaces, 72 // that means he's missing jaxb.properties 73 builder.reportError(new IllegalAnnotationException( 74 Messages.MISSING_JAXB_PROPERTIES.format(getPackageName()), 75 this 76 )); 77 // looking at members will only add more errors, so just abort now 78 return; 79 } 80 81 for( M m : nav.getDeclaredMethods(registryClass) ) { 82 XmlElementDecl em = builder.reader.getMethodAnnotation( 83 XmlElementDecl.class, m, this ); 84 85 if(em==null) { 86 if(nav.getMethodName(m).startsWith("create")) { 87 // this is a factory method. visit this class 88 references.add( 89 builder.getTypeInfo(nav.getReturnType(m), 90 new MethodLocatable<M>(this,m,nav))); 91 } 92 93 continue; 94 } 95 96 ElementInfoImpl<T,C,F,M> ei; 97 try { 98 ei = builder.createElementInfo(this,m); 99 } catch (IllegalAnnotationException e) { 100 builder.reportError(e); 101 continue; // recover by ignoring this element 102 } 103 104 // register this mapping 105 // TODO: any chance this could cause a stack overflow (by recursively visiting classes)? 106 builder.typeInfoSet.add(ei,builder); 107 references.add(ei); 108 } 109 } 110 111 public Locatable getUpstream() { 112 return upstream; 113 } 114 115 public Location getLocation() { 116 return nav.getClassLocation(registryClass); 117 } 118 119 public Set<TypeInfo<T,C>> getReferences() { 120 return references; 121 } 122 123 /** 124 * Gets the name of the package that this registry governs. 125 */ 126 public String getPackageName() { 127 return nav.getPackageName(registryClass); 128 } 129 130 public C getClazz() { 131 return registryClass; 132 } 133} 134