| /* |
| * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Distribution License v. 1.0, which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| package com.sun.tools.xjc.model; |
| |
| import java.util.Collection; |
| import java.util.LinkedHashSet; |
| import java.util.Set; |
| import java.util.Map; |
| |
| import jakarta.activation.MimeType; |
| import jakarta.xml.bind.annotation.W3CDomHandler; |
| import javax.xml.namespace.QName; |
| |
| import com.sun.tools.xjc.model.nav.NClass; |
| import com.sun.tools.xjc.model.nav.NType; |
| import com.sun.tools.xjc.model.nav.NavigatorImpl; |
| import org.glassfish.jaxb.core.v2.model.core.ID; |
| import org.glassfish.jaxb.core.v2.model.core.PropertyKind; |
| import org.glassfish.jaxb.core.v2.model.core.ReferencePropertyInfo; |
| import org.glassfish.jaxb.core.v2.model.core.WildcardMode; |
| import com.sun.xml.xsom.XSComponent; |
| |
| import org.xml.sax.Locator; |
| |
| /** |
| * {@link ReferencePropertyInfo} for the compiler. |
| * |
| * @author Kohsuke Kawaguchi |
| */ |
| public final class CReferencePropertyInfo extends CPropertyInfo implements ReferencePropertyInfo<NType,NClass> { |
| |
| /** |
| * True if this property can never be absent legally. |
| */ |
| private final boolean required; |
| |
| /** |
| * List of referenced elements. |
| */ |
| private final Set<CElement> elements = new LinkedHashSet<>(); |
| |
| private final boolean isMixed; |
| private WildcardMode wildcard; |
| private boolean dummy; |
| private boolean content; |
| private boolean isMixedExtendedCust = false; |
| |
| public CReferencePropertyInfo(String name, boolean collection, boolean required, boolean isMixed, XSComponent source, |
| CCustomizations customizations, Locator locator, boolean dummy, boolean content, boolean isMixedExtended) { // 'dummy' and 'content' here for NHIN fix - a hack in order to be able to handle extended mixed types better |
| super(name, (collection||isMixed) && (!dummy), source, customizations, locator); |
| this.isMixed = isMixed; |
| this.required = required; |
| this.dummy = dummy; |
| this.content = content; |
| this.isMixedExtendedCust = isMixedExtended; |
| } |
| |
| @Override |
| public Set<? extends CTypeInfo> ref() { |
| // if(wildcard==null && !isMixed()) |
| // return getElements(); |
| |
| // ugly hack to get the signature right for substitution groups |
| // when a class is generated for elements,they don't form a nice type hierarchy, |
| // so the Java types of the substitution members need to be taken into account |
| // when computing the signature |
| |
| final class RefList extends LinkedHashSet<CTypeInfo> { |
| RefList() { |
| super(elements.size()); |
| addAll(elements); |
| } |
| @Override |
| public boolean addAll( Collection<? extends CTypeInfo> col ) { |
| boolean r = false; |
| for (CTypeInfo e : col) { |
| if(e instanceof CElementInfo) { |
| // UGLY. element substitution is implemented in a way that |
| // the derived elements are not assignable to base elements. |
| // so when we compute the signature, we have to take derived types |
| // into account |
| r |= addAll( ((CElementInfo)e).getSubstitutionMembers()); |
| } |
| r |= add(e); |
| } |
| return r; |
| } |
| } |
| |
| RefList r = new RefList(); |
| if(wildcard!=null) { |
| if(wildcard.allowDom) |
| r.add(CWildcardTypeInfo.INSTANCE); |
| if(wildcard.allowTypedObject) |
| // we aren't really adding an AnyType. |
| // this is a kind of hack to generate Object as a signature |
| r.add(CBuiltinLeafInfo.ANYTYPE); |
| } |
| if(isMixed()) |
| r.add(CBuiltinLeafInfo.STRING); |
| |
| return r; |
| } |
| |
| @Override |
| public Set<CElement> getElements() { |
| return elements; |
| } |
| |
| @Override |
| public boolean isMixed() { |
| return isMixed; |
| } |
| |
| public boolean isDummy() { |
| return dummy; |
| } |
| |
| public boolean isContent() { |
| return content; |
| } |
| |
| public boolean isMixedExtendedCust() { |
| return isMixedExtendedCust; |
| } |
| |
| /** |
| * We'll never use a wrapper element in XJC. Always return null. |
| */ |
| @Deprecated |
| @Override |
| public QName getXmlName() { |
| return null; |
| } |
| |
| /** |
| * Reference properties refer to elements, and none of the Java primitive type |
| * maps to an element. Thus a reference property is always unboxable. |
| */ |
| @Override |
| public boolean isUnboxable() { |
| return false; |
| } |
| |
| // the same as above |
| @Override |
| public boolean isOptionalPrimitive() { |
| return false; |
| } |
| |
| @Override |
| public <V> V accept(CPropertyVisitor<V> visitor) { |
| return visitor.onReference(this); |
| } |
| |
| @Override |
| public <R, P> R accept(CPropertyVisitor2<R, P> visitor, P p) { |
| return visitor.visit(this, p); |
| } |
| |
| @Override |
| public CAdapter getAdapter() { |
| return null; |
| } |
| |
| @Override |
| public PropertyKind kind() { |
| return PropertyKind.REFERENCE; |
| } |
| |
| /** |
| * A reference property can never be ID/IDREF because they always point to |
| * other element classes. |
| */ |
| @Override |
| public ID id() { |
| return ID.NONE; |
| } |
| |
| @Override |
| public WildcardMode getWildcard() { |
| return wildcard; |
| } |
| |
| public void setWildcard(WildcardMode mode) { |
| this.wildcard = mode; |
| } |
| |
| @Override |
| public NClass getDOMHandler() { |
| // TODO: support other DOM handlers |
| if(getWildcard()!=null) |
| return NavigatorImpl.create(W3CDomHandler.class); |
| else |
| return null; |
| } |
| |
| @Override |
| public MimeType getExpectedMimeType() { |
| return null; |
| } |
| |
| @Override |
| public boolean isCollectionNillable() { |
| // in XJC, we never recognize a nillable collection pattern, so this is always false. |
| return false; |
| } |
| |
| @Override |
| public boolean isCollectionRequired() { |
| // in XJC, we never recognize a nillable collection pattern, so this is always false. |
| return false; |
| } |
| |
| // reference property cannot have a type. |
| @Override |
| public QName getSchemaType() { |
| return null; |
| } |
| |
| @Override |
| public boolean isRequired() { |
| return required; |
| } |
| |
| @Override |
| public QName collectElementNames(Map<QName, CPropertyInfo> table) { |
| for (CElement e : elements) { |
| QName n = e.getElementName(); |
| if(table.containsKey(n)) |
| return n; |
| table.put(n,this); |
| } |
| return null; |
| } |
| } |