/******************************************************************************* * Copyright (c) 2008, 2009 Spring IDE Developers * 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: * Spring IDE Developers - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.beans.core.namespaces; import java.util.Collections; import java.util.List; import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration; import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration; import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap; import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery; import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceHelper; import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil; import org.eclipse.wst.xsd.contentmodel.internal.XSDImpl.XSDAttributeUseAdapter; import org.eclipse.xsd.XSDAttributeUse; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Utility class to providing helper methods to work with the tool annotations defined in Spring core. * @author Christian Dupuis * @since 2.0.3 */ @SuppressWarnings("restriction") public abstract class ToolAnnotationUtils { public static final String ASSIGNABLE_TO_ELEMENT = "assignable-to"; public static final String TYPE_ATTRIBUTE = "type"; public static final String EXPECTED_TYPE_ELEMENT = "expected-type"; public static final String EXPECTED_METHOD_ELEMENT = "expected-method"; public static final String TYPE_REF_ATTRIBUTE = "type-ref"; public static final String EXPRESSION_ATTRIBUTE = "expression"; public static final String RESTRITION_ATTRIBUTE = "restriction"; public static final String KIND_ATTRIBUTE = "kind"; public static final String TOOL_NAMESPACE_URI = "http://www.springframework.org/schema/tool"; public static final String ANNOTATION_ELEMENT = "annotation"; /** * Return the {@link CMElementDeclaration} defined for the given node. */ protected static CMElementDeclaration getCMElementDeclaration(Node node) { CMElementDeclaration result = null; if (node.getNodeType() == Node.ELEMENT_NODE) { ModelQuery modelQuery = ModelQueryUtil.getModelQuery(node.getOwnerDocument()); if (modelQuery != null) { result = modelQuery.getCMElementDeclaration((Element) node); } } return result; } /** * Return a list of annotations that are defined for a given attribute for a specific node. */ public static List<Element> getApplicationInformationElements(Node node, String attributeName) { try { // Retrieve the declaration CMElementDeclaration elementDecl = ToolAnnotationUtils.getCMElementDeclaration(node); CMAttributeDeclaration attrDecl = null; // No CMElementDeclaration means no attribute metadata, but // retrieve the declaration for the attribute otherwise if (elementDecl != null) { CMNamedNodeMap attributes = elementDecl.getAttributes(); String noprefixName = DOMNamespaceHelper.getUnprefixedName(attributeName); if (attributes != null) { attrDecl = (CMAttributeDeclaration) attributes.getNamedItem(noprefixName); if (attrDecl == null) { attrDecl = (CMAttributeDeclaration) attributes.getNamedItem(attributeName); } } if (attrDecl instanceof XSDAttributeUseAdapter) { XSDAttributeUse attribute = (XSDAttributeUse) ((XSDAttributeUseAdapter) attrDecl).getKey(); // 1. Check if annotation and tool annotation are actually // present if (attribute.getAttributeDeclaration() != null && attribute.getAttributeDeclaration().getAnnotation() != null && attribute.getAttributeDeclaration().getAnnotation().getApplicationInformation() != null) { return attribute.getAttributeDeclaration().getAnnotation().getApplicationInformation(); } // 2. If no directly attached annotation could be // found, try the referenced type definition if any. if (attribute.getAttributeDeclaration() != null && attribute.getAttributeDeclaration().getTypeDefinition() != null && attribute.getAttributeDeclaration().getTypeDefinition().getAnnotation() != null && attribute.getAttributeDeclaration().getTypeDefinition().getAnnotation() .getApplicationInformation() != null) { return attribute.getAttributeDeclaration().getTypeDefinition().getAnnotation() .getApplicationInformation(); } } } } catch (Exception e) { // On RAD we get: java.lang.ClassCastException: org.eclipse.xsd.impl.XSDAttributeUseImpl incompatible with // org.eclipse.xsd.XSDAttributeUse } return Collections.emptyList(); } /** * Returns a instance of {@link ToolAnnotationData}. This data holder carries information of the annotation values. */ public static ToolAnnotationData getToolAnnotationData(Node annotation) { ToolAnnotationData data = new ToolAnnotationData(); data.setKind(getAttribute(annotation, KIND_ATTRIBUTE)); NodeList children = annotation.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (EXPECTED_TYPE_ELEMENT.equals(child.getLocalName()) && TOOL_NAMESPACE_URI.equals(child.getNamespaceURI())) { data.setExpectedType(getAttribute(child, TYPE_ATTRIBUTE)); } else if (ASSIGNABLE_TO_ELEMENT.equals(child.getLocalName()) && TOOL_NAMESPACE_URI.equals(child.getNamespaceURI())) { data.setAssignableTo(getAttribute(child, TYPE_ATTRIBUTE)); data.setAssignableToRestriction(getAttribute(child, RESTRITION_ATTRIBUTE)); } else if (EXPECTED_METHOD_ELEMENT.equals(child.getLocalName()) && TOOL_NAMESPACE_URI.equals(child.getNamespaceURI())) { data.setExpectedMethodType(getAttribute(child, TYPE_ATTRIBUTE)); data.setExpectedMethodRef(getAttribute(child, TYPE_REF_ATTRIBUTE)); data.setExpectedMethodExpression(getAttribute(child, EXPRESSION_ATTRIBUTE)); } } return data; } private static final String getAttribute(Node node, String attributeName) { if (hasAttribute(node, attributeName)) { return node.getAttributes().getNamedItem(attributeName).getNodeValue(); } return null; } private static final boolean hasAttribute(Node node, String attributeName) { return (node != null && node.hasAttributes() && node.getAttributes().getNamedItem(attributeName) != null); } /** * Helper class carrying information from attribute annotations. */ public static class ToolAnnotationData { private String kind; private String assignableTo; private String assignableToRestriction; private String expectedType; private String expectedMethodType; private String expectedMethodRef; private String expectedMethodExpression; public String getKind() { return kind; } public String getAssignableTo() { return assignableTo; } public String getExpectedType() { return expectedType; } public String getAssignableToRestriction() { return assignableToRestriction; } public void setAssignableToRestriction(String assignableToRestriction) { this.assignableToRestriction = assignableToRestriction; } public String getExpectedMethodType() { return expectedMethodType; } public void setExpectedMethodType(String expectedMethodType) { this.expectedMethodType = expectedMethodType; } public String getExpectedMethodRef() { return expectedMethodRef; } public void setExpectedMethodRef(String expectedMethodRef) { this.expectedMethodRef = expectedMethodRef; } public String getExpectedMethodExpression() { return expectedMethodExpression; } public void setExpectedMethodExpression(String expectedMethodExpression) { this.expectedMethodExpression = expectedMethodExpression; } public void setKind(String kind) { this.kind = kind; } public void setAssignableTo(String assignableTo) { this.assignableTo = assignableTo; } public void setExpectedType(String expectedType) { this.expectedType = expectedType; } } }