blob: 68ae49e7ce1af09c421a1352280d6e0b3739ea8f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Oracle - initial API and implementation
*******************************************************************************/
package org.eclipse.jpt.jaxb.eclipselink.core.internal.context.java;
import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.QName;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.resource.java.Annotation;
import org.eclipse.jpt.common.core.resource.java.NestableAnnotation;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.internal.Bag;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SubListIterableWrapper;
import org.eclipse.jpt.common.utility.internal.iterables.SuperListIterableWrapper;
import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
import org.eclipse.jpt.jaxb.core.context.XmlElement;
import org.eclipse.jpt.jaxb.core.context.XmlElementWrapper;
import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaXmlElementsMapping;
import org.eclipse.jpt.jaxb.core.resource.java.XmlElementAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlElementWrapperAnnotation;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlElementsMapping;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlPath;
import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessageBuilder;
import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessages;
import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.ELJaxb;
import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.XmlPathAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
public class ELJavaXmlElementsMapping
extends GenericJavaXmlElementsMapping
implements ELXmlElementsMapping {
protected final ContextListContainer<ELJavaXmlPath, XmlPathAnnotation> xmlPathContainer;
public ELJavaXmlElementsMapping(JaxbPersistentAttribute parent) {
super(parent);
this.xmlPathContainer = buildXmlPathContainer();
}
// ***** sync/update *****
@Override
public void synchronizeWithResourceModel() {
super.synchronizeWithResourceModel();
this.xmlPathContainer.synchronizeWithResourceModel();
}
@Override
public void update() {
super.update();
this.xmlPathContainer.update();
}
// ***** xmlPaths *****
public ListIterable<ELXmlPath> getXmlPaths() {
return new SuperListIterableWrapper<ELXmlPath>(xmlPathContainer.getContextElements());
}
public int getXmlPathsSize() {
return this.xmlPathContainer.getContextElementsSize();
}
public ELXmlPath addXmlPath(int index) {
XmlPathAnnotation annotation = (XmlPathAnnotation) getJavaResourceAttribute().addAnnotation(index, ELJaxb.XML_PATH);
return this.xmlPathContainer.addContextElement(index, annotation);
}
public void removeXmlPath(int index) {
getJavaResourceAttribute().removeAnnotation(index, ELJaxb.XML_PATH);
this.xmlPathContainer.removeContextElement(index);
}
public void moveXmlPath(int targetIndex, int sourceIndex) {
getJavaResourceAttribute().moveAnnotation(targetIndex, sourceIndex, ELJaxb.XML_PATH);
this.xmlPathContainer.moveContextElement(targetIndex, sourceIndex);
}
protected ELJavaXmlPath buildXmlPath(XmlPathAnnotation xmlPathAnnotation) {
return new ELJavaXmlPath(this, new XmlPathContext(xmlPathAnnotation));
}
protected ContextListContainer<ELJavaXmlPath, XmlPathAnnotation> buildXmlPathContainer() {
XmlPathContainer container = new XmlPathContainer();
container.initialize();
return container;
}
protected ListIterable<XmlPathAnnotation> getXmlPathAnnotations() {
return new SubListIterableWrapper<NestableAnnotation, XmlPathAnnotation>(
getJavaResourceAttribute().getAnnotations(ELJaxb.XML_PATH));
}
// ***** misc *****
@Override
protected XmlElement buildXmlElement(XmlElementAnnotation xmlElementAnnotation) {
return new ELJavaXmlElement(this, new XmlElementContext(xmlElementAnnotation));
}
@Override
protected XmlElementWrapper buildXmlElementWrapper() {
return new ELJavaXmlElementWrapper(this, new XmlElementWrapperContext());
}
// ***** validation *****
@Override
public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
super.validate(messages, reporter, astRoot);
if (getXmlPathsSize() > 0 ) {
validateXmlPaths(messages, reporter, astRoot);
}
}
protected void validateXmlPaths(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
Iterator<XmlElement> xmlElements = getXmlElements().iterator();
Iterator<ELJavaXmlPath> xmlPaths = this.xmlPathContainer.getContextElements().iterator();
while (xmlElements.hasNext() && xmlPaths.hasNext()) {
xmlElements.next();
xmlPaths.next();
}
if (xmlElements.hasNext()) {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
ELJaxbValidationMessages.XML_PATH__INSUFFICIENT_XML_PATHS_FOR_XML_ELEMENTS,
this,
getXmlPathsTextRange(astRoot)));
}
while (xmlPaths.hasNext()) {
ELJavaXmlPath xmlPath = xmlPaths.next();
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
ELJaxbValidationMessages.XML_PATH__INSUFFICIENT_XML_ELEMENTS_FOR_XML_PATHS,
this,
xmlPath.getValidationTextRange(astRoot)));
}
for (ELJavaXmlPath xmlPath : this.xmlPathContainer.getContextElements()) {
xmlPath.validate(messages, reporter, astRoot);
}
}
@Override
protected void validateDuplicateQName(XmlElement xmlElement, Bag<QName> xmlElementQNames,
List<IMessage> messages, CompilationUnit astRoot) {
if (getXmlPathsSize() == 0) {
super.validateDuplicateQName(xmlElement, xmlElementQNames, messages, astRoot);
}
}
protected TextRange getXmlPathsTextRange(CompilationUnit astRoot) {
Annotation annotation = getJavaResourceAttribute().getAnnotation(ELJaxb.XML_PATHS);
if (annotation == null) {
annotation = getJavaResourceAttribute().getAnnotation(0, ELJaxb.XML_PATH);
}
return annotation.getTextRange(astRoot);
}
protected class XmlPathContainer
extends ContextListContainer<ELJavaXmlPath, XmlPathAnnotation> {
@Override
protected String getContextElementsPropertyName() {
return ELXmlElementsMapping.XML_PATHS_LIST;
}
@Override
protected ELJavaXmlPath buildContextElement(XmlPathAnnotation resourceElement) {
return ELJavaXmlElementsMapping.this.buildXmlPath(resourceElement);
}
@Override
protected ListIterable<XmlPathAnnotation> getResourceElements() {
return ELJavaXmlElementsMapping.this.getXmlPathAnnotations();
}
@Override
protected XmlPathAnnotation getResourceElement(ELJavaXmlPath contextElement) {
// in the context of this mapping, there will never be an ELXmlPath without an annotation
return contextElement.getAnnotation();
}
// public int indexOf(Xml)
}
protected class XmlPathContext
implements ELJavaXmlPath.Context {
protected XmlPathAnnotation annotation;
protected XmlPathContext(XmlPathAnnotation annotation) {
this.annotation = annotation;
}
public XmlPathAnnotation getAnnotation() {
return this.annotation;
}
}
protected class XmlElementContext
extends GenericJavaXmlElementsMapping.XmlElementContext
implements ELJavaXmlElement.Context {
protected XmlElementContext(XmlElementAnnotation annotation) {
super(annotation);
}
public boolean hasXmlPath() {
return ELJavaXmlElementsMapping.this.getXmlPathsSize() > 0;
}
}
protected class XmlElementWrapperContext
implements ELJavaXmlElementWrapper.Context {
public XmlElementWrapperAnnotation getAnnotation() {
return ELJavaXmlElementsMapping.this.getXmlElementWrapperAnnotation();
}
public boolean hasXmlPath() {
return ELJavaXmlElementsMapping.this.getXmlPathsSize() > 0;
}
}
}