blob: 8c7a989c4a1faa984a65d6d60bdda41547d92db6 [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.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.Filter;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.jaxb.core.JaxbNode;
import org.eclipse.jpt.jaxb.core.context.JaxbClassMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbPackage;
import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
import org.eclipse.jpt.jaxb.core.internal.context.java.AbstractJavaContextNode;
import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELClassMapping;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNode;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNodesMapping;
import org.eclipse.jpt.jaxb.eclipselink.core.internal.context.xpath.java.XPath;
import org.eclipse.jpt.jaxb.eclipselink.core.internal.context.xpath.java.XPathFactory;
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.XmlJoinNodeAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
public class ELJavaXmlJoinNode
extends AbstractJavaContextNode
implements ELXmlJoinNode {
protected String xmlPath;
protected String referencedXmlPath;
protected Context context;
public ELJavaXmlJoinNode(JavaContextNode parent, Context context) {
super(parent);
this.context = context;
initXmlPath();
initReferencedXmlPath();
}
protected JaxbPackage getJaxbPackage() {
return getClassMapping().getJaxbType().getJaxbPackage();
}
// ***** sync/update *****
@Override
public void synchronizeWithResourceModel() {
super.synchronizeWithResourceModel();
syncXmlPath();
syncReferencedXmlPath();
}
// ***** xmlPath *****
public String getXmlPath() {
return this.xmlPath;
}
public void setXmlPath(String xmlPath) {
getAnnotation().setXmlPath(xmlPath);
setXmlPath_(xmlPath);
}
protected void setXmlPath_(String xmlPath) {
String old = this.xmlPath;
this.xmlPath = xmlPath;
firePropertyChanged(XML_PATH_PROPERTY, old, this.xmlPath);
}
protected void initXmlPath() {
this.xmlPath = getAnnotation().getXmlPath();
}
protected void syncXmlPath() {
setXmlPath_(getAnnotation().getXmlPath());
}
// ***** referencedXmlPath *****
public String getReferencedXmlPath() {
return this.referencedXmlPath;
}
public void setReferencedXmlPath(String referencedXmlPath) {
getAnnotation().setReferencedXmlPath(referencedXmlPath);
setReferencedXmlPath_(referencedXmlPath);
}
protected void setReferencedXmlPath_(String referencedXmlPath) {
String old = this.referencedXmlPath;
this.referencedXmlPath = referencedXmlPath;
firePropertyChanged(REFERENCED_XML_PATH_PROPERTY, old, this.referencedXmlPath);
}
protected void initReferencedXmlPath() {
this.referencedXmlPath = getAnnotation().getReferencedXmlPath();
}
protected void syncReferencedXmlPath() {
setReferencedXmlPath_(getAnnotation().getReferencedXmlPath());
}
protected XmlJoinNodeAnnotation getAnnotation() {
return this.context.getAnnotation();
}
protected ELXmlJoinNodesMapping getAttributeMapping() {
return this.context.getAttributeMapping();
}
protected JaxbClassMapping getClassMapping() {
return getAttributeMapping().getClassMapping();
}
// ***** content assist *****
@Override
public Iterable<String> getJavaCompletionProposals(
int pos, Filter<String> filter, CompilationUnit astRoot) {
if (getAnnotation().xmlPathTouches(pos, astRoot) && this.xmlPath != null) {
XsdTypeDefinition xsdType = getClassMapping().getXsdTypeDefinition();
XPath xpath = XPathFactory.instance().getXpath(this.xmlPath);
return xpath.getCompletionProposals(new XmlPathContext(astRoot), xsdType, pos, filter);
}
if (getAnnotation().referencedXmlPathTouches(pos, astRoot) && this.referencedXmlPath != null) {
XsdTypeDefinition xsdType = getAttributeMapping().getReferencedXsdTypeDefinition();
XPath xpath = XPathFactory.instance().getXpath(this.referencedXmlPath);
Iterable<String> result = xpath.getCompletionProposals(new ReferencedXmlPathContext(astRoot), xsdType, pos, filter);
ELClassMapping referencedClassMapping = this.context.getAttributeMapping().getReferencedClassMapping();
if (referencedClassMapping != null) {
result = new CompositeIterable<String>(
result,
StringTools.convertToJavaStringLiterals(referencedClassMapping.getKeyXPaths()));
}
return CollectionTools.sortedSet(result);
}
return EmptyIterable.instance();
}
// ***** validation *****
@Override
public TextRange getValidationTextRange(CompilationUnit astRoot) {
return getAnnotation().getTextRange(astRoot);
}
@Override
public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
super.validate(messages, reporter, astRoot);
validateXmlPath(messages, astRoot);
validateReferencedXmlPath(messages, astRoot);
}
protected void validateXmlPath(List<IMessage> messages, CompilationUnit astRoot) {
if (StringTools.stringIsEmpty(this.xmlPath)) {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
ELJaxbValidationMessages.XML_JOIN_NODE__XML_PATH_NOT_SPECIFIED,
ELJavaXmlJoinNode.this,
getXmlPathTextRange(astRoot)));
return;
}
if (this.xmlPath.startsWith(XPath.DELIM)) {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
ELJaxbValidationMessages.XPATH__ROOT_NOT_SUPPORTED,
ELJavaXmlJoinNode.this,
getXmlPathTextRange(astRoot)));
return;
}
XsdTypeDefinition xsdType = getClassMapping().getXsdTypeDefinition();
XPath xpath = XPathFactory.instance().getXpath(this.xmlPath);
xpath.validate(new XmlPathContext(astRoot), xsdType, messages);
}
protected void validateReferencedXmlPath(List<IMessage> messages, CompilationUnit astRoot) {
if (StringTools.stringIsEmpty(this.referencedXmlPath)) {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
ELJaxbValidationMessages.XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_SPECIFIED,
ELJavaXmlJoinNode.this,
getReferencedXmlPathTextRange(astRoot)));
return;
}
if (this.referencedXmlPath.startsWith(XPath.DELIM)) {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
ELJaxbValidationMessages.XPATH__ROOT_NOT_SUPPORTED,
ELJavaXmlJoinNode.this,
getReferencedXmlPathTextRange(astRoot)));
return;
}
ELClassMapping referencedClassMapping = this.context.getAttributeMapping().getReferencedClassMapping();
if (referencedClassMapping != null &&
! CollectionTools.contains(referencedClassMapping.getKeyXPaths(), this.referencedXmlPath)) {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
ELJaxbValidationMessages.XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_IN_REFERENCED_CLASS_KEYS,
new String[] { referencedClassMapping.getJaxbType().getFullyQualifiedName(), this.referencedXmlPath },
ELJavaXmlJoinNode.this,
getReferencedXmlPathTextRange(astRoot)));
}
XsdTypeDefinition xsdType = getAttributeMapping().getReferencedXsdTypeDefinition();
XPath xpath = XPathFactory.instance().getXpath(this.referencedXmlPath);
xpath.validate(new ReferencedXmlPathContext(astRoot), xsdType, messages);
}
protected TextRange getXmlPathTextRange(CompilationUnit astRoot) {
// should never be null
return getAnnotation().getXmlPathTextRange(astRoot);
}
protected TextRange getReferencedXmlPathTextRange(CompilationUnit astRoot) {
// should never be null
return getAnnotation().getReferencedXmlPathTextRange(astRoot);
}
public interface Context {
XmlJoinNodeAnnotation getAnnotation();
ELXmlJoinNodesMapping getAttributeMapping();
}
protected abstract class XPathContext
implements XPath.Context {
protected CompilationUnit astRoot;
protected XPathContext(CompilationUnit astRoot) {
this.astRoot = astRoot;
}
public JaxbNode getContextObject() {
return ELJavaXmlJoinNode.this;
}
public JaxbPackage getJaxbPackage() {
return ELJavaXmlJoinNode.this.getJaxbPackage();
}
}
protected class XmlPathContext
extends XPathContext {
protected XmlPathContext(CompilationUnit astRoot) {
super(astRoot);
}
public TextRange getTextRange() {
return ELJavaXmlJoinNode.this.getXmlPathTextRange(this.astRoot);
}
}
protected class ReferencedXmlPathContext
extends XPathContext {
protected ReferencedXmlPathContext(CompilationUnit astRoot) {
super(astRoot);
}
public TextRange getTextRange() {
return ELJavaXmlJoinNode.this.getReferencedXmlPathTextRange(this.astRoot);
}
}
}