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:
020: package org.netbeans.modules.xslt.mapper.model;
021:
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.xml.axi.AXIComponent;
026: import org.netbeans.modules.xml.axi.AXIType;
027: import org.netbeans.modules.xml.axi.AbstractAttribute;
028: import org.netbeans.modules.xml.axi.AbstractElement;
029: import org.netbeans.modules.xml.axi.Attribute;
030: import org.netbeans.modules.xml.axi.Element;
031: import org.netbeans.modules.xslt.mapper.model.nodes.TreeNode;
032: import org.netbeans.modules.xslt.mapper.model.targettree.AXIUtils;
033: import org.netbeans.modules.xslt.mapper.model.targettree.SchemaNode;
034: import org.netbeans.modules.xslt.mapper.model.targettree.StylesheetNode;
035: import org.netbeans.modules.xslt.mapper.view.XsltMapper;
036: import org.netbeans.modules.xslt.model.AttrValueTamplateHolder;
037: import org.netbeans.modules.xslt.model.AttributeValueTemplate;
038: import org.netbeans.modules.xslt.model.NamespaceSpec;
039: import org.netbeans.modules.xslt.model.SequenceConstructor;
040: import org.netbeans.modules.xslt.model.SequenceElement;
041: import org.netbeans.modules.xslt.model.XslComponent;
042: import org.netbeans.modules.xslt.model.XslModel;
043:
044: /**
045: * Constructs missing XSLT components which are required to
046: * the specified SchemaNode be presented in the XSLT document.
047: *
048: * The XSL model transaction is started and ended automatically if recessary.
049: */
050:
051: public class BranchConstructor {
052: private boolean transactionStarted = false;
053: private boolean exitTranactionOnFinish = true;
054: private SchemaNode startFromNode;
055: private XsltMapper mapper;
056: private XslModel myModel;
057:
058: public BranchConstructor(SchemaNode node, XsltMapper mapper) {
059: startFromNode = node;
060: this .mapper = mapper;
061: myModel = mapper.getContext().getXSLModel();
062: }
063:
064: /**
065: * Allows preventing end transaction on finish.
066: * This method should be used carefully.
067: */
068: public void exitTranactionOnFinish(boolean newValue) {
069: exitTranactionOnFinish = newValue;
070: }
071:
072: public XslComponent construct() {
073: XslComponent result = null;
074:
075: try {
076: result = createXslComponent(startFromNode);
077: } finally {
078: if (exitTranactionOnFinish && myModel != null
079: && transactionStarted) {
080: myModel.endTransaction();
081: }
082: }
083: return result;
084: }
085:
086: private XslComponent createXslComponent(TreeNode node) {
087: XslComponent result = null;
088: //
089: if (node instanceof StylesheetNode) {
090: result = (XslComponent) node.getDataObject();
091: } else if (node instanceof SchemaNode) {
092: TreeNode parent = node.getParent();
093: XslComponent parent_xsl = createXslComponent(parent);
094: if (parent_xsl != null) {
095: //
096: // Start transaction if necessary
097: if (!transactionStarted && myModel != null) {
098: if (!myModel.isIntransaction()) {
099: transactionStarted = myModel.startTransaction();
100: }
101: }
102: //
103: result = createXslElementOrAttribute(parent_xsl, node
104: .getType(), mapper);
105: }
106: }
107: //
108: return result;
109: }
110:
111: public static XslComponent createXslElementOrAttribute(
112: XslComponent parent, AXIComponent type, XsltMapper mapper) {
113: assert (parent instanceof SequenceConstructor);
114: XslModel model = parent.getModel();
115: XslComponent nameHolder = null;
116: if (type instanceof AbstractAttribute) {
117: nameHolder = model.getFactory().createAttribute();
118: } else if (type instanceof AbstractElement) {
119: nameHolder = model.getFactory().createElement();
120: } else {
121: assert false : "Cant recognize element type for new XSL element";
122: }
123: //
124: if (nameHolder != null) {
125: AttributeValueTemplate nameAVT;
126: AttributeValueTemplate namespaceAVT = null;
127: //
128: String name = ((AXIType) type).getName();
129: if (AxiomUtils.isUnqualified(type)) {
130: nameAVT = ((AttrValueTamplateHolder) nameHolder)
131: .createTemplate(name);
132: namespaceAVT = ((AttrValueTamplateHolder) nameHolder)
133: .createTemplate("");
134: } else {
135: String namespace = type.getTargetNamespace();
136: QName elementQName = new QName(namespace, name);
137: nameAVT = ((AttrValueTamplateHolder) nameHolder)
138: .createTemplate(elementQName);
139: }
140:
141: int index = calculateNodeIndex(parent, type, mapper);
142: //
143: if (model.isIntransaction()) {
144: //
145: ((AttrValueTamplateHolder) nameHolder).setName(nameAVT);
146: if (namespaceAVT != null) {
147: ((NamespaceSpec) nameHolder)
148: .setNamespace(namespaceAVT);
149: }
150: //
151: ((SequenceConstructor) parent).addSequenceChild(
152: (SequenceElement) nameHolder, index);
153: } else {
154: model.startTransaction();
155: try {
156: //
157: ((AttrValueTamplateHolder) nameHolder)
158: .setName(nameAVT);
159: if (namespaceAVT != null) {
160: ((NamespaceSpec) nameHolder)
161: .setNamespace(namespaceAVT);
162: }
163: //
164: ((SequenceConstructor) parent).addSequenceChild(
165: (SequenceElement) nameHolder, index);
166: } finally {
167: model.endTransaction();
168: }
169: }
170: }
171: return nameHolder;
172: }
173:
174: public static boolean containsXslElementOrAttribute(
175: XslComponent parent, AXIComponent checkedChildType,
176: XsltMapper mapper) {
177: AXIComponent parent_type = AXIUtils.getType(parent, mapper);
178: List<AXIComponent> axi_child_types = AXIUtils
179: .getChildTypes(parent_type);
180: int child_typeIndex = axi_child_types.indexOf(checkedChildType);
181: if (child_typeIndex == -1)
182: return false;
183:
184: List<XslComponent> xsl_children = parent.getChildren();
185: for (int i = 0; i < xsl_children.size(); i++) {
186: AXIComponent childType = AXIUtils.getType(xsl_children
187: .get(i), mapper);
188: String checkedChildName = null, childName = null;
189: if ((checkedChildType instanceof Element)
190: && (childType instanceof Element)) {
191: checkedChildName = ((Element) checkedChildType)
192: .getName();
193: childName = ((Element) childType).getName();
194: }
195: if ((checkedChildType instanceof Attribute)
196: && (childType instanceof Attribute)) {
197: checkedChildName = ((Attribute) checkedChildType)
198: .getName();
199: childName = ((Attribute) childType).getName();
200: }
201: if ((checkedChildName != null) && (childName != null)
202: && (checkedChildName.equals(childName))) {
203: return true;
204: }
205: }
206: return false;
207: }
208:
209: private static int calculateNodeIndex(XslComponent parent_xsl,
210: AXIComponent type, XsltMapper mapper) {
211: AXIComponent parent_type = AXIUtils.getType(parent_xsl, mapper);
212: List<AXIComponent> axi_children = AXIUtils
213: .getChildTypes(parent_type);
214: int type_index = axi_children.indexOf(type);
215: if (type_index == -1) {
216: return 0;
217: }
218: List<XslComponent> xsl_children = parent_xsl.getChildren();
219: for (int n = 0; n < xsl_children.size(); n++) {
220: AXIComponent child_type = AXIUtils.getType(xsl_children
221: .get(n), mapper);
222: int comp_index = axi_children.indexOf(child_type);
223: if (comp_index > type_index) {
224: return n;
225: }
226: }
227: return xsl_children.size();
228: }
229: }
|