325N/A/*
325N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A */
325N/A
325N/Apackage com.sun.tools.internal.xjc.api.impl.j2s;
325N/A
325N/Aimport java.io.IOException;
325N/Aimport java.util.ArrayList;
325N/Aimport java.util.Collection;
325N/Aimport java.util.HashMap;
325N/Aimport java.util.Iterator;
325N/Aimport java.util.List;
325N/Aimport java.util.Map;
325N/A
325N/Aimport javax.xml.bind.SchemaOutputResolver;
325N/Aimport javax.xml.bind.annotation.XmlList;
325N/Aimport javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
325N/Aimport javax.xml.namespace.QName;
325N/Aimport javax.xml.transform.Result;
325N/A
325N/Aimport com.sun.mirror.declaration.FieldDeclaration;
325N/Aimport com.sun.mirror.declaration.MethodDeclaration;
325N/Aimport com.sun.mirror.declaration.TypeDeclaration;
325N/Aimport com.sun.mirror.type.TypeMirror;
325N/Aimport com.sun.mirror.type.PrimitiveType;
325N/Aimport com.sun.tools.internal.xjc.api.ErrorListener;
325N/Aimport com.sun.tools.internal.xjc.api.J2SJAXBModel;
325N/Aimport com.sun.tools.internal.xjc.api.Reference;
325N/Aimport com.sun.xml.internal.bind.v2.model.annotation.AnnotationReader;
325N/Aimport com.sun.xml.internal.bind.v2.model.core.ArrayInfo;
325N/Aimport com.sun.xml.internal.bind.v2.model.core.ClassInfo;
325N/Aimport com.sun.xml.internal.bind.v2.model.core.Element;
325N/Aimport com.sun.xml.internal.bind.v2.model.core.ElementInfo;
325N/Aimport com.sun.xml.internal.bind.v2.model.core.EnumLeafInfo;
325N/Aimport com.sun.xml.internal.bind.v2.model.core.NonElement;
325N/Aimport com.sun.xml.internal.bind.v2.model.core.Ref;
325N/Aimport com.sun.xml.internal.bind.v2.model.core.TypeInfoSet;
325N/Aimport com.sun.xml.internal.bind.v2.model.nav.Navigator;
325N/Aimport com.sun.xml.internal.bind.v2.schemagen.XmlSchemaGenerator;
325N/Aimport com.sun.xml.internal.txw2.output.ResultFactory;
325N/A
325N/A/**
325N/A * @author Kohsuke Kawaguchi (kk@kohsuke.org)
325N/A */
325N/Afinal class JAXBModelImpl implements J2SJAXBModel {
325N/A
325N/A private final Map<QName,Reference> additionalElementDecls;
325N/A
325N/A private final List<String> classList = new ArrayList<String>();
325N/A
325N/A private final TypeInfoSet<TypeMirror,TypeDeclaration,FieldDeclaration,MethodDeclaration> types;
325N/A
325N/A private final AnnotationReader<TypeMirror,TypeDeclaration,FieldDeclaration,MethodDeclaration> reader;
325N/A
325N/A /**
325N/A * Lazily created schema generator.
325N/A */
325N/A private XmlSchemaGenerator<TypeMirror,TypeDeclaration,FieldDeclaration,MethodDeclaration> xsdgen;
325N/A
325N/A /**
325N/A * Look up table from an externally visible {@link Reference} object
325N/A * to our internal format.
325N/A */
325N/A private final Map<Reference,NonElement<TypeMirror,TypeDeclaration>> refMap =
325N/A new HashMap<Reference, NonElement<TypeMirror,TypeDeclaration>>();
325N/A
325N/A public JAXBModelImpl(TypeInfoSet<TypeMirror, TypeDeclaration, FieldDeclaration, MethodDeclaration> types,
325N/A AnnotationReader<TypeMirror, TypeDeclaration, FieldDeclaration, MethodDeclaration> reader,
325N/A Collection<Reference> rootClasses,
325N/A Map<QName, Reference> additionalElementDecls) {
325N/A this.types = types;
325N/A this.reader = reader;
325N/A this.additionalElementDecls = additionalElementDecls;
325N/A
325N/A Navigator<TypeMirror,TypeDeclaration,FieldDeclaration,MethodDeclaration> navigator = types.getNavigator();
325N/A
325N/A for( ClassInfo<TypeMirror,TypeDeclaration> i : types.beans().values() ) {
325N/A classList.add(i.getName());
325N/A }
325N/A
325N/A for(ArrayInfo<TypeMirror,TypeDeclaration> a : types.arrays().values()) {
325N/A String javaName = navigator.getTypeName(a.getType());
325N/A classList.add(javaName);
325N/A }
325N/A
325N/A for( EnumLeafInfo<TypeMirror,TypeDeclaration> l : types.enums().values() ) {
325N/A QName tn = l.getTypeName();
325N/A if(tn!=null) {
325N/A String javaName = navigator.getTypeName(l.getType());
325N/A classList.add(javaName);
325N/A }
325N/A }
325N/A
325N/A for (Reference ref : rootClasses)
325N/A refMap.put(ref,getXmlType(ref));
325N/A
325N/A // check for collision between "additional" ones and the ones given to JAXB
325N/A // and eliminate duplication
325N/A Iterator<Map.Entry<QName, Reference>> itr = additionalElementDecls.entrySet().iterator();
325N/A while(itr.hasNext()) {
325N/A Map.Entry<QName, Reference> entry = itr.next();
325N/A if(entry.getValue()==null) continue;
325N/A
325N/A NonElement<TypeMirror,TypeDeclaration> xt = getXmlType(entry.getValue());
325N/A
325N/A assert xt!=null;
325N/A refMap.put(entry.getValue(),xt);
325N/A if(xt instanceof ClassInfo) {
325N/A ClassInfo<TypeMirror,TypeDeclaration> xct = (ClassInfo<TypeMirror,TypeDeclaration>) xt;
325N/A Element<TypeMirror,TypeDeclaration> elem = xct.asElement();
325N/A if(elem!=null && elem.getElementName().equals(entry.getKey())) {
325N/A itr.remove();
325N/A continue;
325N/A }
325N/A }
325N/A ElementInfo<TypeMirror,TypeDeclaration> ei = types.getElementInfo(null,entry.getKey());
325N/A if(ei!=null && ei.getContentType()==xt)
325N/A itr.remove();
325N/A }
325N/A }
325N/A
325N/A public List<String> getClassList() {
325N/A return classList;
325N/A }
325N/A
325N/A public QName getXmlTypeName(Reference javaType) {
325N/A NonElement<TypeMirror,TypeDeclaration> ti = refMap.get(javaType);
325N/A
325N/A if(ti!=null)
325N/A return ti.getTypeName();
325N/A
325N/A return null;
325N/A }
325N/A
325N/A private NonElement<TypeMirror,TypeDeclaration> getXmlType(Reference r) {
325N/A if(r==null)
325N/A throw new IllegalArgumentException();
325N/A
325N/A XmlJavaTypeAdapter xjta = r.annotations.getAnnotation(XmlJavaTypeAdapter.class);
325N/A XmlList xl = r.annotations.getAnnotation(XmlList.class);
325N/A
325N/A Ref<TypeMirror, TypeDeclaration> ref = new Ref<TypeMirror, TypeDeclaration>(
325N/A reader,types.getNavigator(),r.type,xjta,xl);
325N/A
325N/A return types.getTypeInfo(ref);
325N/A }
325N/A
325N/A public void generateSchema(SchemaOutputResolver outputResolver, ErrorListener errorListener) throws IOException {
325N/A getSchemaGenerator().write(outputResolver,errorListener);
325N/A }
325N/A
325N/A public void generateEpisodeFile(Result output) {
325N/A getSchemaGenerator().writeEpisodeFile(ResultFactory.createSerializer(output));
325N/A }
325N/A
325N/A private synchronized XmlSchemaGenerator<TypeMirror, TypeDeclaration, FieldDeclaration, MethodDeclaration> getSchemaGenerator() {
325N/A if(xsdgen==null) {
325N/A xsdgen = new XmlSchemaGenerator<TypeMirror,TypeDeclaration,FieldDeclaration,MethodDeclaration>( types.getNavigator(), types );
325N/A
325N/A for (Map.Entry<QName, Reference> e : additionalElementDecls.entrySet()) {
325N/A Reference value = e.getValue();
325N/A if(value!=null) {
325N/A NonElement<TypeMirror, TypeDeclaration> typeInfo = refMap.get(value);
325N/A if(typeInfo==null)
325N/A throw new IllegalArgumentException(e.getValue()+" was not specified to JavaCompiler.bind");
325N/A xsdgen.add(e.getKey(),!(value.type instanceof PrimitiveType),typeInfo);
325N/A } else {
325N/A xsdgen.add(e.getKey(),false,null);
325N/A }
325N/A }
325N/A }
325N/A return xsdgen;
325N/A }
325N/A}