| /* |
| * 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.AbstractList; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| |
| import jakarta.activation.MimeType; |
| 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.reader.RawTypeSet; |
| import org.glassfish.jaxb.core.v2.model.core.ElementPropertyInfo; |
| import org.glassfish.jaxb.core.v2.model.core.ID; |
| import org.glassfish.jaxb.core.v2.model.core.PropertyKind; |
| import com.sun.xml.xsom.XSComponent; |
| |
| import org.xml.sax.Locator; |
| |
| /** |
| * {@link ElementPropertyInfo} for the compiler. |
| * |
| * @author Kohsuke Kawaguchi |
| */ |
| public final class CElementPropertyInfo extends CPropertyInfo implements ElementPropertyInfo<NType,NClass> { |
| |
| /** |
| * True if this property can never be absent legally. |
| */ |
| private final boolean required; |
| |
| private final MimeType expectedMimeType; |
| /** |
| * |
| * <p> |
| * Currently, this is set inside {@link RawTypeSet} in a very ugly way. |
| */ |
| private CAdapter adapter; |
| |
| private final boolean isValueList; |
| |
| private ID id; |
| |
| |
| /** |
| * List of referenced types. |
| */ |
| private final List<CTypeRef> types = new ArrayList<>(); |
| |
| private final List<CNonElement> ref = new AbstractList<>() { |
| @Override |
| public CNonElement get(int index) { |
| return getTypes().get(index).getTarget(); |
| } |
| |
| @Override |
| public int size() { |
| return getTypes().size(); |
| } |
| }; |
| |
| // TODO: shouldn't they get id and expectedMimeType from TypeUses of CTypeRef? |
| public CElementPropertyInfo(String name, CollectionMode collection, ID id, MimeType expectedMimeType, XSComponent source, |
| CCustomizations customizations, Locator locator, boolean required) { |
| super(name, collection.col, source, customizations, locator); |
| this.required = required; |
| this.id = id; |
| this.expectedMimeType = expectedMimeType; |
| this.isValueList = collection.val; |
| } |
| |
| @Override |
| public ID id() { |
| return id; |
| } |
| |
| @Override |
| public List<CTypeRef> getTypes() { |
| return types; |
| } |
| |
| @Override |
| public List<CNonElement> ref() { |
| return ref; |
| } |
| |
| @Override |
| public QName getSchemaType() { |
| if(types.size()!=1) |
| // if more than one kind is here, can't produce @XmlSchemaType. |
| // TODO: is it allowed to have one generated if types |
| return null; |
| |
| CTypeRef t = types.get(0); |
| if(needsExplicitTypeName(t.getTarget(),t.typeName)) |
| return t.typeName; |
| else |
| return null; |
| } |
| |
| /** |
| * XJC never uses the wrapper element. Always return null. |
| */ |
| @Deprecated |
| @Override |
| public QName getXmlName() { |
| return null; |
| } |
| |
| @Override |
| public boolean isCollectionRequired() { |
| // in XJC, we never recognize a nillable collection pattern, so this is always false. |
| return false; |
| } |
| |
| @Override |
| public boolean isCollectionNillable() { |
| // in XJC, we never recognize a nillable collection pattern, so this is always false. |
| return false; |
| } |
| |
| @Override |
| public boolean isRequired() { |
| return required; |
| } |
| |
| @Override |
| public boolean isValueList() { |
| return isValueList; |
| } |
| |
| @Override |
| public boolean isUnboxable() { |
| if(!isCollection() && !required) |
| // if the property can be legally absent, it's not unboxable |
| return false; |
| // we need to have null to represent the absence of value. not unboxable. |
| for (CTypeRef t : getTypes()) { |
| if(t.isNillable()) |
| return false; |
| } |
| return super.isUnboxable(); |
| } |
| |
| @Override |
| public boolean isOptionalPrimitive() { |
| // we need to have null to represent the absence of value. not unboxable. |
| for (CTypeRef t : getTypes()) { |
| if(t.isNillable()) |
| return false; |
| } |
| return !isCollection() && !required && super.isUnboxable(); |
| } |
| |
| @Override |
| public <V> V accept(CPropertyVisitor<V> visitor) { |
| return visitor.onElement(this); |
| } |
| |
| @Override |
| public <R, P> R accept(CPropertyVisitor2<R, P> visitor, P p) { |
| return visitor.visit(this, p); |
| } |
| |
| @Override |
| public CAdapter getAdapter() { |
| return adapter; |
| } |
| |
| public void setAdapter(CAdapter a) { |
| assert adapter==null; |
| adapter = a; |
| } |
| |
| @Override |
| public PropertyKind kind() { |
| return PropertyKind.ELEMENT; |
| } |
| |
| @Override |
| public MimeType getExpectedMimeType() { |
| return expectedMimeType; |
| } |
| |
| public enum CollectionMode { |
| NOT_REPEATED(false,false), |
| REPEATED_ELEMENT(true,false), |
| REPEATED_VALUE(true,true); |
| |
| private final boolean col,val; |
| |
| CollectionMode(boolean col,boolean val) { |
| this.col = col; |
| this.val = val; |
| } |
| |
| public boolean isRepeated() { return col; } |
| } |
| |
| @Override |
| public QName collectElementNames(Map<QName, CPropertyInfo> table) { |
| for (CTypeRef t : types) { |
| QName n = t.getTagName(); |
| if(table.containsKey(n)) return n; |
| table.put(n, this); |
| } |
| return null; |
| } |
| } |