001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.bind.v2.model.impl;
027:
028: import java.util.LinkedHashSet;
029: import java.util.Set;
030:
031: import javax.xml.bind.annotation.XmlElementDecl;
032:
033: import com.sun.xml.internal.bind.v2.model.annotation.Locatable;
034: import com.sun.xml.internal.bind.v2.model.annotation.MethodLocatable;
035: import com.sun.xml.internal.bind.v2.model.core.RegistryInfo;
036: import com.sun.xml.internal.bind.v2.model.core.TypeInfo;
037: import com.sun.xml.internal.bind.v2.model.nav.Navigator;
038: import com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationException;
039: import com.sun.xml.internal.bind.v2.runtime.Location;
040: import com.sun.xml.internal.bind.v2.ContextFactory;
041:
042: /**
043: * Implementation of {@link RegistryInfo}.
044: *
045: * @author Kohsuke Kawaguchi
046: */
047: // experimenting with shorter type parameters for <T,C,F,M> quadruple.
048: // the idea is that they show so often that you'd understand the meaning
049: // without relying on the whole name.
050: final class RegistryInfoImpl<T, C, F, M> implements Locatable,
051: RegistryInfo<T, C> {
052:
053: final C registryClass;
054: private final Locatable upstream;
055: private final Navigator<T, C, F, M> nav;
056:
057: /**
058: * Types that are referenced from this registry.
059: */
060: private final Set<TypeInfo<T, C>> references = new LinkedHashSet<TypeInfo<T, C>>();
061:
062: /**
063: * Picks up references in this registry to other types.
064: */
065: RegistryInfoImpl(ModelBuilder<T, C, F, M> builder,
066: Locatable upstream, C registryClass) {
067: this .nav = builder.nav;
068: this .registryClass = registryClass;
069: this .upstream = upstream;
070: builder.registries.put(getPackageName(), this );
071:
072: if (nav.getDeclaredField(registryClass,
073: ContextFactory.USE_JAXB_PROPERTIES) != null) {
074: // the user is trying to use ObjectFactory that we generate for interfaces,
075: // that means he's missing jaxb.properties
076: builder.reportError(new IllegalAnnotationException(
077: Messages.MISSING_JAXB_PROPERTIES
078: .format(getPackageName()), this ));
079: // looking at members will only add more errors, so just abort now
080: return;
081: }
082:
083: for (M m : nav.getDeclaredMethods(registryClass)) {
084: XmlElementDecl em = builder.reader.getMethodAnnotation(
085: XmlElementDecl.class, m, this );
086:
087: if (em == null) {
088: if (nav.getMethodName(m).startsWith("create")) {
089: // this is a factory method. visit this class
090: references.add(builder.getTypeInfo(nav
091: .getReturnType(m), new MethodLocatable<M>(
092: this , m, nav)));
093: }
094:
095: continue;
096: }
097:
098: ElementInfoImpl<T, C, F, M> ei;
099: try {
100: ei = builder.createElementInfo(this , m);
101: } catch (IllegalAnnotationException e) {
102: builder.reportError(e);
103: continue; // recover by ignoring this element
104: }
105:
106: // register this mapping
107: // TODO: any chance this could cause a stack overflow (by recursively visiting classes)?
108: builder.typeInfoSet.add(ei, builder);
109: references.add(ei);
110: }
111: }
112:
113: public Locatable getUpstream() {
114: return upstream;
115: }
116:
117: public Location getLocation() {
118: return nav.getClassLocation(registryClass);
119: }
120:
121: public Set<TypeInfo<T, C>> getReferences() {
122: return references;
123: }
124:
125: /**
126: * Gets the name of the package that this registry governs.
127: */
128: public String getPackageName() {
129: return nav.getPackageName(registryClass);
130: }
131:
132: public C getClazz() {
133: return registryClass;
134: }
135: }
|