src/share/jaxws_classes/com/sun/tools/internal/xjc/generator/bean/PackageOutlineImpl.java

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
parent 0
373ffda63c9a
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.internal.xjc.generator.bean;
aoqi@0 27
aoqi@0 28 import java.util.Collections;
aoqi@0 29 import java.util.HashMap;
aoqi@0 30 import java.util.HashSet;
aoqi@0 31 import java.util.Map;
aoqi@0 32 import java.util.Set;
aoqi@0 33
aoqi@0 34 import javax.xml.bind.annotation.XmlNsForm;
aoqi@0 35 import javax.xml.bind.annotation.XmlSchema;
aoqi@0 36 import javax.xml.namespace.QName;
aoqi@0 37
aoqi@0 38 import com.sun.codemodel.internal.JDefinedClass;
aoqi@0 39 import com.sun.codemodel.internal.JPackage;
aoqi@0 40 import com.sun.tools.internal.xjc.generator.annotation.spec.XmlSchemaWriter;
aoqi@0 41 import com.sun.tools.internal.xjc.model.CAttributePropertyInfo;
aoqi@0 42 import com.sun.tools.internal.xjc.model.CClassInfo;
aoqi@0 43 import com.sun.tools.internal.xjc.model.CElement;
aoqi@0 44 import com.sun.tools.internal.xjc.model.CElementPropertyInfo;
aoqi@0 45 import com.sun.tools.internal.xjc.model.CPropertyInfo;
aoqi@0 46 import com.sun.tools.internal.xjc.model.CPropertyVisitor;
aoqi@0 47 import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
aoqi@0 48 import com.sun.tools.internal.xjc.model.CTypeRef;
aoqi@0 49 import com.sun.tools.internal.xjc.model.CValuePropertyInfo;
aoqi@0 50 import com.sun.tools.internal.xjc.model.Model;
aoqi@0 51 import com.sun.tools.internal.xjc.outline.PackageOutline;
aoqi@0 52 import com.sun.tools.internal.xjc.outline.Aspect;
aoqi@0 53
aoqi@0 54 /**
aoqi@0 55 * {@link PackageOutline} enhanced with schema2java specific
aoqi@0 56 * information.
aoqi@0 57 *
aoqi@0 58 * @author
aoqi@0 59 * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com), Martin Grebac (martin.grebac@oracle.com)
aoqi@0 60 */
aoqi@0 61 public final class PackageOutlineImpl implements PackageOutline {
aoqi@0 62 private final Model _model;
aoqi@0 63 private final JPackage _package;
aoqi@0 64 private final ObjectFactoryGenerator objectFactoryGenerator;
aoqi@0 65
aoqi@0 66 /*package*/ final Set<ClassOutlineImpl> classes = new HashSet<ClassOutlineImpl>();
aoqi@0 67 private final Set<ClassOutlineImpl> classesView = Collections.unmodifiableSet(classes);
aoqi@0 68
aoqi@0 69 private String mostUsedNamespaceURI;
aoqi@0 70 private XmlNsForm elementFormDefault;
aoqi@0 71 private XmlNsForm attributeFormDefault;
aoqi@0 72
aoqi@0 73 /**
aoqi@0 74 * The namespace URI most commonly used in classes in this package.
aoqi@0 75 * This should be used as the namespace URI for {@link XmlSchema#namespace()}.
aoqi@0 76 *
aoqi@0 77 * <p>
aoqi@0 78 * Null if no default
aoqi@0 79 *
aoqi@0 80 * @see #calcDefaultValues().
aoqi@0 81 */
aoqi@0 82 public String getMostUsedNamespaceURI() {
aoqi@0 83 return mostUsedNamespaceURI;
aoqi@0 84 }
aoqi@0 85
aoqi@0 86 /**
aoqi@0 87 * The attribute form default for this package.
aoqi@0 88 * <p>
aoqi@0 89 * The value is computed by examining what would yield the smallest generated code.
aoqi@0 90 */
aoqi@0 91 public XmlNsForm getAttributeFormDefault() {
aoqi@0 92 assert attributeFormDefault!=null;
aoqi@0 93 return attributeFormDefault;
aoqi@0 94 }
aoqi@0 95
aoqi@0 96 /**
aoqi@0 97 * The element form default for this package.
aoqi@0 98 * <p>
aoqi@0 99 * The value is computed by examining what would yield the smallest generated code.
aoqi@0 100 */
aoqi@0 101 public XmlNsForm getElementFormDefault() {
aoqi@0 102 assert elementFormDefault!=null;
aoqi@0 103 return elementFormDefault;
aoqi@0 104 }
aoqi@0 105
aoqi@0 106 public JPackage _package() {
aoqi@0 107 return _package;
aoqi@0 108 }
aoqi@0 109
aoqi@0 110 public ObjectFactoryGenerator objectFactoryGenerator() {
aoqi@0 111 return objectFactoryGenerator;
aoqi@0 112 }
aoqi@0 113
aoqi@0 114 public Set<ClassOutlineImpl> getClasses() {
aoqi@0 115 return classesView;
aoqi@0 116 }
aoqi@0 117
aoqi@0 118 public JDefinedClass objectFactory() {
aoqi@0 119 return objectFactoryGenerator.getObjectFactory();
aoqi@0 120 }
aoqi@0 121
aoqi@0 122 protected PackageOutlineImpl( BeanGenerator outline, Model model, JPackage _pkg ) {
aoqi@0 123 this._model = model;
aoqi@0 124 this._package = _pkg;
aoqi@0 125 switch(model.strategy) {
aoqi@0 126 case BEAN_ONLY:
aoqi@0 127 objectFactoryGenerator = new PublicObjectFactoryGenerator(outline,model,_pkg);
aoqi@0 128 break;
aoqi@0 129 case INTF_AND_IMPL:
aoqi@0 130 objectFactoryGenerator = new DualObjectFactoryGenerator(outline,model,_pkg);
aoqi@0 131 break;
aoqi@0 132 default:
aoqi@0 133 throw new IllegalStateException();
aoqi@0 134 }
aoqi@0 135 }
aoqi@0 136
aoqi@0 137 /**
aoqi@0 138 * Compute the most common namespace URI in this package
aoqi@0 139 * (to put into {@link XmlSchema#namespace()} and what value
aoqi@0 140 * we should put into {@link XmlSchema#elementFormDefault()}.
aoqi@0 141 *
aoqi@0 142 * This method is called after {@link #classes} field is filled up.
aoqi@0 143 */
aoqi@0 144 public void calcDefaultValues() {
aoqi@0 145 // short-circuit if xjc was told not to generate package level annotations in
aoqi@0 146 // package-info.java
aoqi@0 147 if(!_model.isPackageLevelAnnotations()) {
aoqi@0 148 mostUsedNamespaceURI = "";
aoqi@0 149 elementFormDefault = XmlNsForm.UNQUALIFIED;
aoqi@0 150 return;
aoqi@0 151 }
aoqi@0 152
aoqi@0 153 // used to visit properties
aoqi@0 154 CPropertyVisitor<Void> propVisitor = new CPropertyVisitor<Void>() {
aoqi@0 155 public Void onElement(CElementPropertyInfo p) {
aoqi@0 156 for (CTypeRef tr : p.getTypes()) {
aoqi@0 157 countURI(propUriCountMap, tr.getTagName());
aoqi@0 158 }
aoqi@0 159 return null;
aoqi@0 160 }
aoqi@0 161
aoqi@0 162 public Void onReference(CReferencePropertyInfo p) {
aoqi@0 163 for (CElement e : p.getElements()) {
aoqi@0 164 countURI(propUriCountMap, e.getElementName());
aoqi@0 165 }
aoqi@0 166 return null;
aoqi@0 167 }
aoqi@0 168
aoqi@0 169 public Void onAttribute(CAttributePropertyInfo p) {
aoqi@0 170 return null;
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 public Void onValue(CValuePropertyInfo p) {
aoqi@0 174 return null;
aoqi@0 175 }
aoqi@0 176 };
aoqi@0 177
aoqi@0 178
aoqi@0 179 for (ClassOutlineImpl co : classes) {
aoqi@0 180 CClassInfo ci = co.target;
aoqi@0 181 countURI(uriCountMap, ci.getTypeName());
aoqi@0 182 countURI(uriCountMap, ci.getElementName());
aoqi@0 183
aoqi@0 184 for( CPropertyInfo p : ci.getProperties() )
aoqi@0 185 p.accept(propVisitor);
aoqi@0 186 }
aoqi@0 187 mostUsedNamespaceURI = getMostUsedURI(uriCountMap);
aoqi@0 188
aoqi@0 189 elementFormDefault = getFormDefault();
aoqi@0 190 attributeFormDefault = XmlNsForm.UNQUALIFIED;
aoqi@0 191 try {
aoqi@0 192 XmlNsForm modelValue = _model.getAttributeFormDefault(mostUsedNamespaceURI);
aoqi@0 193 attributeFormDefault = modelValue;
aoqi@0 194 } catch (Exception e) {
aoqi@0 195 // ignore and accept default
aoqi@0 196 }
aoqi@0 197
aoqi@0 198 // generate package-info.java
aoqi@0 199 // we won't get this far if the user specified -npa
aoqi@0 200 if(!mostUsedNamespaceURI.equals("") || elementFormDefault==XmlNsForm.QUALIFIED || (attributeFormDefault == XmlNsForm.QUALIFIED)) {
aoqi@0 201 XmlSchemaWriter w = _model.strategy.getPackage(_package, Aspect.IMPLEMENTATION).annotate2(XmlSchemaWriter.class);
aoqi@0 202 if(!mostUsedNamespaceURI.equals(""))
aoqi@0 203 w.namespace(mostUsedNamespaceURI);
aoqi@0 204 if(elementFormDefault==XmlNsForm.QUALIFIED)
aoqi@0 205 w.elementFormDefault(elementFormDefault);
aoqi@0 206 if(attributeFormDefault==XmlNsForm.QUALIFIED)
aoqi@0 207 w.attributeFormDefault(attributeFormDefault);
aoqi@0 208 }
aoqi@0 209 }
aoqi@0 210
aoqi@0 211 // Map to keep track of how often each type or element uri is used in this package
aoqi@0 212 // mostly used to calculate mostUsedNamespaceURI
aoqi@0 213 private HashMap<String, Integer> uriCountMap = new HashMap<String, Integer>();
aoqi@0 214
aoqi@0 215 // Map to keep track of how often each property uri is used in this package
aoqi@0 216 // used to calculate elementFormDefault
aoqi@0 217 private HashMap<String, Integer> propUriCountMap = new HashMap<String, Integer>();
aoqi@0 218
aoqi@0 219 /**
aoqi@0 220 * pull the uri out of the specified QName and keep track of it in the
aoqi@0 221 * specified hash map
aoqi@0 222 *
aoqi@0 223 * @param qname
aoqi@0 224 */
aoqi@0 225 private void countURI(HashMap<String, Integer> map, QName qname) {
aoqi@0 226 if (qname == null) return;
aoqi@0 227
aoqi@0 228 String uri = qname.getNamespaceURI();
aoqi@0 229
aoqi@0 230 if (map.containsKey(uri)) {
aoqi@0 231 map.put(uri, map.get(uri) + 1);
aoqi@0 232 } else {
aoqi@0 233 map.put(uri, 1);
aoqi@0 234 }
aoqi@0 235 }
aoqi@0 236
aoqi@0 237 /**
aoqi@0 238 * Iterate through the hash map looking for the namespace used
aoqi@0 239 * most frequently. Ties are arbitrarily broken by the order
aoqi@0 240 * in which the map keys are iterated over.
aoqi@0 241 *
aoqi@0 242 * <p>
aoqi@0 243 * Because JAX-WS often reassigns the "" namespace URI,
aoqi@0 244 * and when that happens it unintentionally also renames (normally
aoqi@0 245 * unqualified) local elements, prefer non-"" URI when there's a tie.
aoqi@0 246 */
aoqi@0 247 private String getMostUsedURI(HashMap<String, Integer> map) {
aoqi@0 248 String mostPopular = null;
aoqi@0 249 int count = 0;
aoqi@0 250
aoqi@0 251 for (Map.Entry<String,Integer> e : map.entrySet()) {
aoqi@0 252 String uri = e.getKey();
aoqi@0 253 int uriCount = e.getValue();
aoqi@0 254 if (mostPopular == null) {
aoqi@0 255 mostPopular = uri;
aoqi@0 256 count = uriCount;
aoqi@0 257 } else {
aoqi@0 258 if (uriCount > count || (uriCount==count && mostPopular.equals(""))) {
aoqi@0 259 mostPopular = uri;
aoqi@0 260 count = uriCount;
aoqi@0 261 }
aoqi@0 262 }
aoqi@0 263 }
aoqi@0 264
aoqi@0 265 if (mostPopular == null) return "";
aoqi@0 266 return mostPopular;
aoqi@0 267 }
aoqi@0 268
aoqi@0 269 /**
aoqi@0 270 * Calculate the element form defaulting.
aoqi@0 271 *
aoqi@0 272 * Compare the most frequently used property URI to the most frequently used
aoqi@0 273 * element/type URI. If they match, then return QUALIFIED
aoqi@0 274 */
aoqi@0 275 private XmlNsForm getFormDefault() {
aoqi@0 276 if (getMostUsedURI(propUriCountMap).equals("")) return XmlNsForm.UNQUALIFIED;
aoqi@0 277 else return XmlNsForm.QUALIFIED;
aoqi@0 278 }
aoqi@0 279
aoqi@0 280 }

mercurial