001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019: package org.netbeans.modules.xslt.mapper.model.targettree;
020:
021: import java.util.ArrayList;
022: import java.util.List;
023: import javax.xml.namespace.QName;
024: import org.netbeans.modules.soa.ui.axinodes.AxiomUtils;
025: import org.netbeans.modules.soa.ui.axinodes.AxiomUtils.PathItem;
026: import org.netbeans.modules.xml.axi.AXIComponent;
027: import org.netbeans.modules.xml.axi.AXIDocument;
028: import org.netbeans.modules.xml.axi.AXIType;
029: import org.netbeans.modules.xml.axi.AbstractAttribute;
030: import org.netbeans.modules.xml.axi.AbstractElement;
031: import org.netbeans.modules.xml.axi.Attribute;
032: import org.netbeans.modules.xml.axi.Element;
033: import org.netbeans.modules.xslt.mapper.model.nodes.TreeNode;
034: import org.netbeans.modules.xslt.mapper.view.XsltMapper;
035: import org.netbeans.modules.xslt.model.AttributeValueTemplate;
036: import org.netbeans.modules.xslt.model.Instruction;
037: import org.netbeans.modules.xslt.model.Template;
038: import org.netbeans.modules.xslt.model.XslComponent;
039: import org.netbeans.modules.xslt.model.XslVisitor;
040: import org.netbeans.modules.xslt.model.XslVisitorAdapter;
041:
042: /**
043: *
044: * @author Alexey
045: */
046: public class AXIUtils {
047:
048: /**
049: * Checks if XSL component this node represents creates an element in output tree of given schema type
050: * @returns true if types are the same
051: **/
052: public static boolean isSameSchemaType(XslComponent xslc,
053: AXIComponent axic) {
054: TypeCheckVisitor visitor = new TypeCheckVisitor(axic);
055: xslc.accept(visitor);
056: return visitor.isMatching();
057: }
058:
059: public static class TypeCheckVisitor extends XslVisitorAdapter {
060: private AXIComponent axic;
061: private boolean isMatching = false;
062:
063: public TypeCheckVisitor(AXIComponent axic) {
064: this .axic = axic;
065: }
066:
067: public boolean isMatching() {
068: return isMatching;
069: }
070:
071: public void visit(
072: org.netbeans.modules.xslt.model.Attribute attribute) {
073: if (axic instanceof org.netbeans.modules.xml.axi.Attribute) {
074: AttributeValueTemplate atv = attribute.getName();
075: if (atv != null) {
076: isMatching = compareName(atv.getQName());
077: }
078: }
079: }
080:
081: public void visit(
082: org.netbeans.modules.xslt.model.Element element) {
083: if (axic instanceof org.netbeans.modules.xml.axi.Element) {
084: AttributeValueTemplate atv = element.getName();
085: if (atv != null) {
086: isMatching = compareName(atv.getQName());
087: }
088: }
089: }
090:
091: public void visit(
092: org.netbeans.modules.xslt.model.LiteralResultElement element) {
093: if (axic instanceof org.netbeans.modules.xml.axi.Element) {
094: QName qname = element.getQName();
095: isMatching = compareName(qname);
096: }
097: }
098:
099: private boolean compareName(QName qname) {
100: if (qname == null) {
101: return false;
102: }
103: //
104: if (AxiomUtils.isUnqualified(axic)) {
105: return qname.getLocalPart().equals(
106: ((AXIType) axic).getName());
107: } else {
108: return qname.getLocalPart().equals(
109: ((AXIType) axic).getName())
110: && qname.getNamespaceURI().equals(
111: axic.getTargetNamespace());
112: }
113: }
114:
115: }
116:
117: /**
118: * Call visitor for all children of type Attribute and Element
119: **/
120: public static abstract class ElementVisitor {
121: public abstract void visit(AXIComponent component);
122:
123: public void visitSubelements(AXIComponent axic) {
124: if (axic instanceof Element) {
125: visitSubelements((Element) axic);
126: } else if (axic instanceof AXIDocument) {
127: visitSubelements((AXIDocument) axic);
128: }
129: }
130:
131: protected void visitSubelements(Element element) {
132: for (AbstractAttribute a : element.getAttributes()) {
133: if (a instanceof Attribute) {
134: visit(a);
135: }
136: }
137:
138: for (AbstractElement e : element.getChildElements()) {
139: if (e instanceof Element) {
140: visit(e);
141: }
142: }
143: }
144:
145: protected void visitSubelements(AXIDocument doc) {
146:
147: for (AbstractElement e : doc.getChildElements()) {
148: if (e instanceof Element) {
149: visit(e);
150: }
151: }
152:
153: }
154:
155: }
156:
157: public static List<AXIComponent> getChildTypes(AXIComponent axic) {
158:
159: final List<AXIComponent> result = new ArrayList<AXIComponent>();
160:
161: if (axic != null) {
162:
163: new AXIUtils.ElementVisitor() {
164: public void visit(AXIComponent c) {
165: result.add(c);
166: }
167: }.visitSubelements(axic);
168: }
169:
170: return result;
171:
172: }
173:
174: /**
175: * Prepares XPath for the specified Schema node.
176: */
177: public static List<PathItem> prepareSimpleXPath(
178: final SchemaNode schemaNode) {
179: //
180: // Collects Path Items first
181: ArrayList<PathItem> path = new ArrayList<PathItem>();
182: TreeNode currNode = schemaNode;
183: SchemaNode lastProcessedSchemaNode = null;
184: while (currNode != null && currNode instanceof SchemaNode) {
185: lastProcessedSchemaNode = (SchemaNode) currNode;
186: if (currNode instanceof PredicatedSchemaNode) {
187: PredicatedSchemaNode psn = (PredicatedSchemaNode) currNode;
188: String pred = psn.getPredicatedAxiComp()
189: .getPredicatesText();
190: AxiomUtils.processNode(lastProcessedSchemaNode
191: .getType(), pred, path);
192: } else {
193: AxiomUtils.processNode(lastProcessedSchemaNode
194: .getType(), null, path);
195: }
196: //
197: currNode = currNode.getParent();
198: }
199: //
200: // Add parent elements to ensure that the XPath would be absolute
201: if (lastProcessedSchemaNode != null) {
202: AXIComponent axiComponent = lastProcessedSchemaNode
203: .getType();
204: if (axiComponent != null) {
205: AXIComponent parentAxiComponent = axiComponent
206: .getParent();
207: while (true) {
208: if (parentAxiComponent == null) {
209: break;
210: }
211: //
212: AxiomUtils.processNode(parentAxiComponent, null,
213: path);
214: //
215: parentAxiComponent = parentAxiComponent.getParent();
216: }
217: }
218: }
219: //
220: return path;
221: }
222:
223: public static AXIComponent getType(XslComponent xslc,
224: XsltMapper mapper) {
225: if (xslc == null) {
226: return null;
227: }
228: XslComponent xsl_parent = xslc.getParent();
229:
230: if (xslc instanceof org.netbeans.modules.xslt.model.Element
231: || xslc instanceof org.netbeans.modules.xslt.model.Attribute) {
232: AXIComponent axi_parent = getType(xsl_parent, mapper);
233: if (axi_parent != null) {
234: for (AXIComponent type : axi_parent.getChildElements()) {
235: if (type == null || type.getPeer() == null
236: || type.getPeer().getModel() == null) {
237: continue;
238: }
239: if (AXIUtils.isSameSchemaType(xslc, type)) {
240: return type;
241: }
242: }
243: }
244: } else if (xslc instanceof org.netbeans.modules.xslt.model.Template) { //no declaration nodes fond downtree
245: AXIComponent targetType = mapper.getContext()
246: .getTargetType();
247: return targetType != null ? targetType.getModel().getRoot()
248: : null;
249: } else if (xsl_parent != null) {
250: return getType(xsl_parent, mapper);
251: }
252: return null;
253: }
254:
255: }
|