/**
* Copyright © 2006-2016 Web Cohesion (info@webcohesion.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.webcohesion.enunciate.modules.jaxb.model;
import com.webcohesion.enunciate.facets.Facet;
import com.webcohesion.enunciate.facets.HasFacets;
import com.webcohesion.enunciate.javac.decorations.Annotations;
import com.webcohesion.enunciate.javac.decorations.element.DecoratedExecutableElement;
import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement;
import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror;
import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext;
import com.webcohesion.enunciate.modules.jaxb.model.types.XmlType;
import com.webcohesion.enunciate.modules.jaxb.model.types.XmlTypeFactory;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.namespace.QName;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Callable;
/**
* A declaration of a "local" element (defined by a registry).
*
* @author Ryan Heaton
*/
public class LocalElementDeclaration extends DecoratedExecutableElement implements HasFacets, ElementDeclaration {
private final TypeMirror elementType;
private final XmlElementDecl elementDecl;
private final Registry registry;
private final Set<Facet> facets = new TreeSet<Facet>();
private final EnunciateJaxbContext context;
public LocalElementDeclaration(ExecutableElement element, Registry registry, EnunciateJaxbContext context) {
super(element, context.getContext().getProcessingEnvironment());
this.registry = registry;
elementDecl = element.getAnnotation(XmlElementDecl.class);
if (elementDecl == null) {
throw new IllegalArgumentException(element + ": a local element declaration must be annotated with @XmlElementDecl.");
}
List<? extends VariableElement> params = element.getParameters();
if (params.size() != 1) {
throw new IllegalArgumentException(element + ": a local element declaration must have only one parameter.");
}
elementType = params.get(0).asType();
this.facets.addAll(Facet.gatherFacets(registry, context.getContext()));
this.facets.addAll(Facet.gatherFacets(element, context.getContext()));
this.context = context;
}
/**
* The name of the local element.
*
* @return The name of the local element.
*/
public String getName() {
return elementDecl.name();
}
/**
* The namespace of the local element.
*
* @return The namespace of the local element.
*/
public String getNamespace() {
String namespace = elementDecl.namespace();
if ("##default".equals(namespace)) {
namespace = this.registry.getSchema().getNamespace();
}
return "".equals(namespace) ? null : namespace;
}
/**
* The qname of the element.
*
* @return The qname of the element.
*/
public QName getQname() {
return new QName(getNamespace(), getName());
}
/**
* The scope of the local element.
*
* @return The scope of the local element.
*/
public DecoratedTypeElement getElementScope() {
DecoratedTypeElement declaration = null;
DecoratedTypeMirror typeMirror = Annotations.mirrorOf(new Callable<Class<?>>() {
@Override
public Class<?> call() throws Exception {
return elementDecl.scope();
}
}, this.env, XmlElementDecl.GLOBAL.class);
if (typeMirror != null) {
declaration = (DecoratedTypeElement) ((DeclaredType) typeMirror).asElement();
}
return declaration;
}
/**
* The name of the substitution head.
*
* @return The name of the substitution head.
*/
public String getSubstitutionHeadName() {
String shn = elementDecl.substitutionHeadName();
if ("".equals(shn)) {
shn = null;
}
return shn;
}
/**
* The namespace of the substitution head.
*
* @return The namespace of the substitution head.
*/
public String getSubstitutionHeadNamespace() {
String shn = elementDecl.substitutionHeadNamespace();
if ("##default".equals(shn)) {
shn = this.registry.getSchema().getNamespace();
}
return shn;
}
/**
* The substitution group qname.
*
* @return The substitution group qname.
*/
public QName getSubstitutionGroupQName() {
String localPart = getSubstitutionHeadName();
if (localPart == null) {
return null;
}
return new QName(getSubstitutionHeadNamespace(), localPart);
}
/**
* The default value.
*
* @return The default value.
*/
public String getDefaultElementValue() {
String defaultValue = elementDecl.defaultValue();
if ("\u0000".equals(defaultValue)) {
defaultValue = null;
}
return defaultValue;
}
/**
* The type definition for the local element.
*
* @return The type definition for the local element.
*/
public TypeMirror getElementType() {
return elementType;
}
/**
* The element xml type.
*
* @return The element xml type.
*/
public XmlType getElementXmlType() {
return XmlTypeFactory.getXmlType(getParameters().get(0).asType(), this.context);
}
/**
* The facets here applicable.
*
* @return The facets here applicable.
*/
public Set<Facet> getFacets() {
return facets;
}
}