/*****************************************************************************
* This file is part of Rinzo
*
* Author: Claudio Cancinos
* WWW: https://sourceforge.net/projects/editorxml
* Copyright (C): 2008, Claudio Cancinos
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; If not, see <http://www.gnu.org/licenses/>
****************************************************************************/
package ar.com.tadp.xml.rinzo.core.contentassist.processors;
import java.util.Collection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import ar.com.tadp.xml.rinzo.core.contentassist.proposals.ProposalsFactory;
import ar.com.tadp.xml.rinzo.core.model.XMLNode;
import ar.com.tadp.xml.rinzo.core.model.tags.AttributeDefinition;
import ar.com.tadp.xml.rinzo.core.model.tags.TagTypeDefinition;
/**
* It generates tags, attributes and attribute values proposals for xml
* elements.
*
* @author ccancinos
*/
public class XMLContentAssistProcessor implements IXMLContentAssistProcessor {
/**
* TODO When adding an attribute with a default value defined in XSD/DTD add
* it.
*/
public void addAttributeProposals(XMLNode currentNode, String prefix, ITextViewer viewer, int offset,
Collection<ICompletionProposal> resultList) {
Collection<String> nodeAttributes = currentNode.getAttributes().keySet();
TagTypeDefinition typeDefinition = currentNode.getTypeDefinition();
for (AttributeDefinition attrDef : typeDefinition.getAttributes()) {
if (attrDef.getName().startsWith(prefix) && !nodeAttributes.contains(attrDef.getName())) {
resultList.add(ProposalsFactory.createAttributeProposal(attrDef, offset, prefix.length()));
}
}
}
public void addAttributeValuesProposals(XMLNode currentNode, String attributeName, String prefix,
ITextViewer viewer, int offset, Collection<ICompletionProposal> resultList) {
AttributeDefinition attributeDefinition = currentNode.getTypeDefinition().getAttribute(prefix);
Collection<String> acceptableValues = null;
int startAttrPrefix = prefix.indexOf("\"");
startAttrPrefix = (startAttrPrefix != -1) ? startAttrPrefix : prefix.indexOf("\'");
String attrPrefix = prefix.substring(startAttrPrefix + 1);
if (attributeDefinition != null) {
acceptableValues = attributeDefinition.getAcceptableValues();
if (!acceptableValues.isEmpty()) {
for (String currentValue : acceptableValues) {
if (currentValue.startsWith(attrPrefix)) {
resultList.add(ProposalsFactory.createAttributeValueProposal(currentValue, offset, attrPrefix.length()));
}
}
}
}
}
public void addCloseTagProposals(XMLNode currentNode, String prefix, ITextViewer viewer, int offset,
Collection<ICompletionProposal> resultList) {
if (currentNode.isTextTag()) {
resultList.add(ProposalsFactory.createEndTagProposal(currentNode.getParent().getTypeDefinition(), offset,
(currentNode.isIncompleteTag() ? currentNode.getContent().trim().length() : 0)));
}
if (currentNode.isIncompleteTag()) {
resultList.add(ProposalsFactory.createIncompleteEndTagProposal(currentNode.getTypeDefinition(), offset,
(currentNode.isIncompleteTag() ? currentNode.getContent().trim().length() : 0)));
resultList.add(ProposalsFactory.createIncompleteClosingEndTagProposal(currentNode.getTypeDefinition(),
offset, (currentNode.isIncompleteTag() ? currentNode.getContent().trim().length() : 0)));
}
}
public void addBodyProposals(XMLNode currentNode, String prefix, ITextViewer viewer, int offset,
Collection<ICompletionProposal> resultList) {
Collection<TagTypeDefinition> validTags;
String tagPrefix = "";
String tagNamespace = "";
int inc = 0;
if(prefix.startsWith("<")) {
prefix = prefix.substring(1);
inc++;
}
if (prefix.contains(":")) {
String[] split = prefix.split(":");
tagNamespace = split[0];
tagPrefix = (split.length == 2) ? split[1] : "";
inc++;
} else {
tagPrefix = prefix;
}
validTags = this.getValidTagsInOffset(currentNode, offset);
for (TagTypeDefinition tagDefinition : validTags) {
if (tagDefinition != null) {
String name = tagDefinition.getName();
String namespace = tagDefinition.getNamespace();
if (tagNamespace.isEmpty()) {
if (name.startsWith(tagPrefix) || namespace.startsWith(tagPrefix)) {
resultList.add(ProposalsFactory.createTagProposal(tagDefinition, offset, tagPrefix.length()
+ (currentNode.isIncompleteTag() ? 1 : 0)));
}
} else {
if (namespace.startsWith(tagNamespace) && name.startsWith(tagPrefix)) {
resultList.add(ProposalsFactory.createTagProposal(tagDefinition, offset, tagPrefix.length()
+ tagNamespace.length() + (currentNode.isIncompleteTag() ? 1 : 0) + inc));
}
}
}
}
}
private Collection<TagTypeDefinition> getValidTagsInOffset(
XMLNode currentNode, int offset) {
Collection<TagTypeDefinition> reference;
if (currentNode.getParent() == null) {
reference = currentNode.getCorrespondingNode().getTypeDefinition().getInnerTags();
} else {
if (currentNode.getOffset() + currentNode.getLength() == offset) {
reference = currentNode.getTypeDefinition().getInnerTags();
} else {
reference = currentNode.getParent().getTypeDefinition().getInnerTags();
}
}
return reference;
}
}