blob: 3b4928d2dc3c1648a8025f2c4b7f32b2f72b74b9 [file] [log] [blame]
/*
* 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;
}
}