All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.tools.xjc.generator.bean.PackageOutlineImpl Maven / Gradle / Ivy

There is a newer version: 4.0.5
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.tools.xjc.generator.bean;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.namespace.QName;

import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JPackage;
import com.sun.tools.xjc.generator.annotation.spec.XmlSchemaWriter;
import com.sun.tools.xjc.model.CAttributePropertyInfo;
import com.sun.tools.xjc.model.CClassInfo;
import com.sun.tools.xjc.model.CElement;
import com.sun.tools.xjc.model.CElementPropertyInfo;
import com.sun.tools.xjc.model.CPropertyInfo;
import com.sun.tools.xjc.model.CPropertyVisitor;
import com.sun.tools.xjc.model.CReferencePropertyInfo;
import com.sun.tools.xjc.model.CTypeRef;
import com.sun.tools.xjc.model.CValuePropertyInfo;
import com.sun.tools.xjc.model.Model;
import com.sun.tools.xjc.outline.PackageOutline;
import com.sun.tools.xjc.outline.Aspect;

/**
 * {@link PackageOutline} enhanced with schema2java specific
 * information.
 * 
 * @author
 *     Kohsuke Kawaguchi ([email protected]), Martin Grebac ([email protected])
 */
public final class PackageOutlineImpl implements PackageOutline {
    private final Model _model;
    private final JPackage _package;
    private final ObjectFactoryGenerator objectFactoryGenerator;

    /*package*/ final Set classes = new HashSet();
    private final Set classesView = Collections.unmodifiableSet(classes);

    private String mostUsedNamespaceURI;
    private XmlNsForm elementFormDefault;
    private XmlNsForm attributeFormDefault;

    /**
     * The namespace URI most commonly used in classes in this package.
     * This should be used as the namespace URI for {@link XmlSchema#namespace()}.
     *
     * 

* Null if no default * * @see #calcDefaultValues(). */ public String getMostUsedNamespaceURI() { return mostUsedNamespaceURI; } /** * The attribute form default for this package. *

* The value is computed by examining what would yield the smallest generated code. */ public XmlNsForm getAttributeFormDefault() { assert attributeFormDefault!=null; return attributeFormDefault; } /** * The element form default for this package. *

* The value is computed by examining what would yield the smallest generated code. */ public XmlNsForm getElementFormDefault() { assert elementFormDefault!=null; return elementFormDefault; } public JPackage _package() { return _package; } public ObjectFactoryGenerator objectFactoryGenerator() { return objectFactoryGenerator; } public Set getClasses() { return classesView; } public JDefinedClass objectFactory() { return objectFactoryGenerator.getObjectFactory(); } protected PackageOutlineImpl( BeanGenerator outline, Model model, JPackage _pkg ) { this._model = model; this._package = _pkg; switch(model.strategy) { case BEAN_ONLY: objectFactoryGenerator = new PublicObjectFactoryGenerator(outline,model,_pkg); break; case INTF_AND_IMPL: objectFactoryGenerator = new DualObjectFactoryGenerator(outline,model,_pkg); break; default: throw new IllegalStateException(); } } /** * Compute the most common namespace URI in this package * (to put into {@link XmlSchema#namespace()} and what value * we should put into {@link XmlSchema#elementFormDefault()}. * * This method is called after {@link #classes} field is filled up. */ public void calcDefaultValues() { // short-circuit if xjc was told not to generate package level annotations in // package-info.java if(!_model.isPackageLevelAnnotations()) { mostUsedNamespaceURI = ""; elementFormDefault = XmlNsForm.UNQUALIFIED; return; } // used to visit properties CPropertyVisitor propVisitor = new CPropertyVisitor() { public Void onElement(CElementPropertyInfo p) { for (CTypeRef tr : p.getTypes()) { countURI(propUriCountMap, tr.getTagName()); } return null; } public Void onReference(CReferencePropertyInfo p) { for (CElement e : p.getElements()) { countURI(propUriCountMap, e.getElementName()); } return null; } public Void onAttribute(CAttributePropertyInfo p) { return null; } public Void onValue(CValuePropertyInfo p) { return null; } }; for (ClassOutlineImpl co : classes) { CClassInfo ci = co.target; countURI(uriCountMap, ci.getTypeName()); countURI(uriCountMap, ci.getElementName()); for( CPropertyInfo p : ci.getProperties() ) p.accept(propVisitor); } mostUsedNamespaceURI = getMostUsedURI(uriCountMap); elementFormDefault = getFormDefault(); attributeFormDefault = XmlNsForm.UNQUALIFIED; try { XmlNsForm modelValue = _model.getAttributeFormDefault(mostUsedNamespaceURI); attributeFormDefault = modelValue; } catch (Exception e) { // ignore and accept default } // generate package-info.java // we won't get this far if the user specified -npa if(!mostUsedNamespaceURI.equals("") || elementFormDefault==XmlNsForm.QUALIFIED || (attributeFormDefault == XmlNsForm.QUALIFIED)) { XmlSchemaWriter w = _model.strategy.getPackage(_package, Aspect.IMPLEMENTATION).annotate2(XmlSchemaWriter.class); if(!mostUsedNamespaceURI.equals("")) w.namespace(mostUsedNamespaceURI); if(elementFormDefault==XmlNsForm.QUALIFIED) w.elementFormDefault(elementFormDefault); if(attributeFormDefault==XmlNsForm.QUALIFIED) w.attributeFormDefault(attributeFormDefault); } } // Map to keep track of how often each type or element uri is used in this package // mostly used to calculate mostUsedNamespaceURI private HashMap uriCountMap = new HashMap(); // Map to keep track of how often each property uri is used in this package // used to calculate elementFormDefault private HashMap propUriCountMap = new HashMap(); /** * pull the uri out of the specified QName and keep track of it in the * specified hash map * * @param qname */ private void countURI(HashMap map, QName qname) { if (qname == null) return; String uri = qname.getNamespaceURI(); if (map.containsKey(uri)) { map.put(uri, map.get(uri) + 1); } else { map.put(uri, 1); } } /** * Iterate through the hash map looking for the namespace used * most frequently. Ties are arbitrarily broken by the order * in which the map keys are iterated over. * *

* Because JAX-WS often reassigns the "" namespace URI, * and when that happens it unintentionally also renames (normally * unqualified) local elements, prefer non-"" URI when there's a tie. */ private String getMostUsedURI(HashMap map) { String mostPopular = null; int count = 0; for (Map.Entry e : map.entrySet()) { String uri = e.getKey(); int uriCount = e.getValue(); if (mostPopular == null) { mostPopular = uri; count = uriCount; } else { if (uriCount > count || (uriCount==count && mostPopular.equals(""))) { mostPopular = uri; count = uriCount; } } } if (mostPopular == null) return ""; return mostPopular; } /** * Calculate the element form defaulting. * * Compare the most frequently used property URI to the most frequently used * element/type URI. If they match, then return QUALIFIED */ private XmlNsForm getFormDefault() { if (getMostUsedURI(propUriCountMap).equals("")) return XmlNsForm.UNQUALIFIED; else return XmlNsForm.QUALIFIED; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy