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.bpel.mapper.model;
021:
022: import java.util.ArrayList;
023: import java.util.List;
024: import javax.swing.tree.TreePath;
025: import javax.xml.namespace.NamespaceContext;
026: import javax.xml.namespace.QName;
027: import org.netbeans.modules.bpel.mapper.multiview.BpelDesignContext;
028: import org.netbeans.modules.bpel.mapper.predicates.AbstractPredicate;
029: import org.netbeans.modules.bpel.mapper.tree.MapperSwingTreeModel;
030: import org.netbeans.modules.bpel.mapper.tree.models.VariableDeclarationWrapper;
031: import org.netbeans.modules.bpel.mapper.tree.spi.MapperTcContext;
032: import org.netbeans.modules.bpel.model.api.AbstractVariableDeclaration;
033: import org.netbeans.modules.bpel.model.api.BpelEntity;
034: import org.netbeans.modules.bpel.model.api.BpelModel;
035: import org.netbeans.modules.bpel.model.api.ContentElement;
036: import org.netbeans.modules.bpel.model.api.PartnerLink;
037: import org.netbeans.modules.bpel.model.api.Process;
038: import org.netbeans.modules.bpel.model.api.VariableDeclaration;
039: import org.netbeans.modules.bpel.model.api.VariableDeclarationScope;
040: import org.netbeans.modules.bpel.model.api.events.VetoException;
041: import org.netbeans.modules.bpel.model.api.support.ExNamespaceContext;
042: import org.netbeans.modules.bpel.model.api.support.InvalidNamespaceException;
043: import org.netbeans.modules.bpel.model.api.support.Roles;
044: import org.netbeans.modules.bpel.model.api.support.XPathModelFactory;
045: import org.netbeans.modules.bpel.model.api.support.XPathBpelVariable;
046: import org.netbeans.modules.soa.mappercore.model.Constant;
047: import org.netbeans.modules.soa.mappercore.model.Link;
048: import org.netbeans.modules.soa.mappercore.model.MapperModel;
049: import org.netbeans.modules.soa.mappercore.model.SourcePin;
050: import org.netbeans.modules.soa.mappercore.model.TreeSourcePin;
051: import org.netbeans.modules.soa.mappercore.model.Vertex;
052: import org.netbeans.modules.soa.mappercore.model.VertexItem;
053: import org.netbeans.modules.xml.schema.model.Attribute;
054: import org.netbeans.modules.xml.xpath.ext.CoreFunctionType;
055: import org.netbeans.modules.xml.xpath.ext.CoreOperationType;
056: import org.netbeans.modules.xml.xpath.ext.LocationStep;
057: import org.netbeans.modules.xml.xpath.ext.StepNodeNameTest;
058: import org.netbeans.modules.xml.xpath.ext.XPathExpression;
059: import org.netbeans.modules.xml.xpath.ext.XPathExpressionPath;
060: import org.netbeans.modules.xml.xpath.ext.XPathModel;
061: import org.netbeans.modules.xml.xpath.ext.XPathNumericLiteral;
062: import org.netbeans.modules.xml.xpath.ext.XPathOperationOrFuntion;
063: import org.netbeans.modules.xml.xpath.ext.XPathStringLiteral;
064: import org.netbeans.modules.xml.xpath.ext.XPathVariableReference;
065: import org.netbeans.modules.xml.xpath.ext.metadata.ExtFunctionMetadata;
066: import org.netbeans.modules.xml.xpath.ext.metadata.StubExtFunction;
067: import org.netbeans.modules.xml.schema.model.SchemaComponent;
068: import org.netbeans.modules.xml.wsdl.model.Part;
069: import org.netbeans.modules.xml.xam.Named;
070: import org.netbeans.modules.xml.xpath.ext.XPathAxis;
071: import org.netbeans.modules.xml.xpath.ext.XPathPredicateExpression;
072: import org.netbeans.modules.xml.xpath.ext.metadata.ArgumentDescriptor;
073: import org.netbeans.modules.xml.xpath.ext.metadata.XPathType;
074: import org.openide.ErrorManager;
075:
076: /**
077: *
078: *
079: * @author nk160297
080: */
081: public class AbstractBpelModelUpdater {
082:
083: protected MapperTcContext mMapperTcContext;
084:
085: public AbstractBpelModelUpdater(MapperTcContext mapperTcContext) {
086: assert mapperTcContext != null;
087: mMapperTcContext = mapperTcContext;
088: }
089:
090: public BpelDesignContext getDesignContext() {
091: return mMapperTcContext.getDesignContextController()
092: .getContext();
093: }
094:
095: public BpelMapperModel getMapperModel() {
096: MapperModel mm = mMapperTcContext.getMapper().getModel();
097: assert mm instanceof BpelMapperModel;
098: return (BpelMapperModel) mm;
099: }
100:
101: //==========================================================================
102:
103: public XPathExprList buildXPathExprList(XPathModel xPathModel,
104: GraphInfoCollector graphInfo) {
105: //
106: ArrayList<XPathExpression> xPathExprList = new ArrayList<XPathExpression>();
107: boolean hasRoot = false;
108: //
109: for (Link link : graphInfo.getTransitLinks()) {
110: TreeSourcePin sourcePin = (TreeSourcePin) link.getSource();
111: TreePath sourceTreePath = sourcePin.getTreePath();
112: TreePathInfo tpInfo = collectTreeInfo(sourceTreePath);
113: //
114: // The XPath for has to be used because there are another
115: // expressions which has to be combined with it.
116: XPathExpression newExpression = createVariableXPath(
117: xPathModel, tpInfo);
118: if (newExpression != null) {
119: xPathModel.fillInStubs(newExpression);
120: xPathExprList.add(newExpression);
121: hasRoot = true;
122: }
123: }
124: //
125: for (Vertex vertex : graphInfo.getPrimaryRoots()) {
126: XPathExpression newExpression = createXPathRecursive(
127: xPathModel, vertex);
128: if (newExpression != null) {
129: xPathModel.fillInStubs(newExpression);
130: xPathExprList.add(newExpression);
131: hasRoot = true;
132: }
133: }
134: //
135: for (Vertex vertex : graphInfo.getSecondryRoots()) {
136: XPathExpression newExpression = createXPathRecursive(
137: xPathModel, vertex);
138: if (newExpression != null) {
139: xPathModel.fillInStubs(newExpression);
140: xPathExprList.add(newExpression);
141: }
142: }
143: //
144: XPathExprList result = new XPathExprList(xPathExprList, hasRoot);
145: return result;
146: }
147:
148: protected void populateContentHolder(ContentElement contentHolder,
149: GraphInfoCollector graphInfo) {
150: //
151: XPathModel xPathModel = XPathModelFactory
152: .create((BpelEntity) contentHolder);
153: //
154: XPathExprList exprList = buildXPathExprList(xPathModel,
155: graphInfo);
156:
157: //
158: String newExprString = exprList.toString();
159: try {
160: if (newExprString != null && newExprString.length() != 0) {
161: contentHolder.setContent(newExprString);
162: } else {
163: contentHolder.setContent(null);
164: }
165: } catch (VetoException ex) {
166: // DO nothing here
167: }
168: }
169:
170: //==========================================================================
171:
172: protected XPathExpression createVariableXPath(
173: XPathModel xPathModel, TreePathInfo tpInfo) {
174: //
175: if (tpInfo == null || tpInfo.varDecl == null) {
176: return null;
177: }
178: //
179: XPathBpelVariable xPathVar = new XPathBpelVariable(
180: tpInfo.varDecl, tpInfo.part);
181: QName varQName = xPathVar.constructXPathName();
182: XPathVariableReference xPathVarRef = xPathModel.getFactory()
183: .newXPathVariableReference(varQName);
184: //
185: if (tpInfo.schemaCompList.isEmpty()) {
186: return xPathVarRef;
187: } else {
188: List<LocationStep> stepList = constructLSteps(xPathModel,
189: tpInfo.schemaCompList);
190: if (stepList != null && !(stepList.isEmpty())) {
191: XPathExpressionPath exprPath = xPathModel
192: .getFactory()
193: .newXPathExpressionPath(
194: xPathVarRef,
195: stepList
196: .toArray(new LocationStep[stepList
197: .size()]));
198: return exprPath;
199: }
200: }
201: //
202: return null;
203: }
204:
205: //==========================================================================
206:
207: protected List<LocationStep> constructLSteps(XPathModel xPathModel,
208: List<Object> sCompList) {
209: if (sCompList == null || sCompList.isEmpty()) {
210: return null;
211: }
212: //
213: ArrayList<LocationStep> result = new ArrayList<LocationStep>();
214: //
215: for (Object stepObj : sCompList) {
216: LocationStep newLocationStep = null;
217: if (stepObj instanceof SchemaComponent) {
218: newLocationStep = constructLStep(xPathModel,
219: (SchemaComponent) stepObj, null);
220: } else if (stepObj instanceof AbstractPredicate) {
221: AbstractPredicate pred = (AbstractPredicate) stepObj;
222: XPathPredicateExpression[] predArr = pred
223: .getPredicates();
224: SchemaComponent sComp = pred.getSComponent();
225: newLocationStep = constructLStep(xPathModel, sComp,
226: predArr);
227: } else if (stepObj instanceof LocationStep) {
228: //
229: // TODO: It would be more correct to do a copy of the stepObj
230: // because of it is owned by another XPathModel.
231: newLocationStep = (LocationStep) stepObj;
232: }
233: //
234: if (newLocationStep != null) {
235: result.add(newLocationStep);
236: }
237: }
238: //
239: return result;
240: }
241:
242: /**
243: * Constructs a LocationStep object by the schema component.
244: * @param xPathModel
245: * @param sComp
246: * @return
247: */
248: protected LocationStep constructLStep(XPathModel xPathModel,
249: SchemaComponent sComp, XPathPredicateExpression[] predArr) {
250: //
251: if (!(sComp instanceof Named)) {
252: return null;
253: }
254: //
255: XPathAxis axis = null;
256: if (sComp instanceof Attribute) {
257: axis = XPathAxis.ATTRIBUTE;
258: } else {
259: axis = XPathAxis.CHILD;
260: }
261: //
262: StepNodeNameTest nameTest = new StepNodeNameTest(xPathModel,
263: sComp);
264: LocationStep newLocationStep = xPathModel.getFactory()
265: .newLocationStep(axis, nameTest, predArr);
266: //
267: return newLocationStep;
268: }
269:
270: //==========================================================================
271:
272: /**
273: * Analyses the specified treePath and collects variouse information to
274: * intermediate object TreePathInfo.
275: * @param treePath
276: * @return
277: */
278: protected TreePathInfo collectTreeInfo(TreePath treePath) {
279: //
280: List<Object> objectPath = MapperSwingTreeModel
281: .convertTreePath(treePath);
282: //
283: TreePathInfo sourceInfo = new TreePathInfo();
284: //
285: // Collect source info according to the tree path
286: for (Object item : objectPath) {
287: //
288: if (item instanceof SchemaComponent
289: || item instanceof AbstractPredicate
290: || item instanceof LocationStep) {
291: sourceInfo.schemaCompList.add(item);
292: } else if (item instanceof AbstractVariableDeclaration) {
293: if (item instanceof VariableDeclarationScope) {
294: continue;
295: } else if (item instanceof VariableDeclarationWrapper) {
296: sourceInfo.varDecl = ((VariableDeclarationWrapper) item)
297: .getDelegate();
298: } else if (item instanceof VariableDeclaration) {
299: sourceInfo.varDecl = (VariableDeclaration) item;
300: }
301: } else if (item instanceof Part) {
302: sourceInfo.part = (Part) item;
303: } else if (item instanceof PartnerLink) {
304: sourceInfo.pLink = (PartnerLink) item;
305: } else if (item instanceof Roles) {
306: sourceInfo.roles = (Roles) item;
307: }
308: }
309: //
310: return sourceInfo;
311: }
312:
313: //==========================================================================
314:
315: protected XPathExpression createXPathRecursive(
316: XPathModel xPathModel, Vertex vertex) {
317: XPathExpression newExpression = createXPath(xPathModel, vertex);
318: //
319: if (newExpression instanceof XPathOperationOrFuntion) {
320: // Operation or Function
321: //
322: // Calculate index of the vertex item to which
323: // the last (in order of appearance) incoming links is connected
324: // or which contains a not empty value (it is equal to connection
325: // to a constant value)
326: int lastConnectedItemIndex = -1;
327: for (int index = 0; index < vertex.getItemCount(); index++) {
328: VertexItem vItem = vertex.getItem(index);
329: if (vItem.isHairline()) {
330: // Skip hirelines
331: continue;
332: }
333: //
334: Object value = vItem.getValue();
335: if (value != null) {
336: lastConnectedItemIndex = index;
337: continue;
338: }
339: //
340: Link incomingLink = vItem.getIngoingLink();
341: if (incomingLink != null) {
342: lastConnectedItemIndex = index;
343: }
344: }
345: //
346: // Process incoming links and inplace values
347: for (int index = 0; index < vertex.getItemCount(); index++) {
348: VertexItem vItem = vertex.getItem(index);
349: if (vItem.isHairline()) {
350: // Skip hirelines
351: continue;
352: }
353: XPathExpression childExpr = null;
354: Link ingoingLink = vItem.getIngoingLink();
355: if (ingoingLink == null) {
356: boolean valueProcessed = false;
357: Object value = vItem.getValue();
358: if (value != null) {
359: // Add value as a constant
360: Object dataObject = vItem.getDataObject();
361: assert dataObject instanceof ArgumentDescriptor;
362: //
363: XPathType argType = ((ArgumentDescriptor) dataObject)
364: .getArgumentType();
365: if (argType == XPathType.NUMBER_TYPE) {
366: if (value instanceof Number) {
367: childExpr = xPathModel.getFactory()
368: .newXPathNumericLiteral(
369: (Number) value);
370: valueProcessed = true;
371: }
372: } else if (argType == XPathType.STRING_TYPE) {
373: if (value instanceof String
374: && ((String) value).length() != 0) {
375: childExpr = xPathModel.getFactory()
376: .newXPathStringLiteral(
377: (String) value);
378: valueProcessed = true;
379: }
380: } else {
381: assert false : "Unsupported constant's type"; // NOI18N
382: }
383: }
384: //
385: // Consider the value is empty or wrong it it is not processed
386: if (!valueProcessed) {
387: //
388: // Vertex item without connected link
389: if (index >= lastConnectedItemIndex) {
390: // There is not any more items with connected links
391: break;
392: }
393: //
394: // The stub() function will be added to output text.
395: // It is necessary to protect place where the following
396: // links are connected. Otherwise the links move to the
397: // first positions after mapper is reloaded.
398: childExpr = new StubExtFunction(xPathModel);
399: }
400: } else {
401: //
402: // Vertex item with connected link
403: SourcePin sourcePin = ingoingLink.getSource();
404: //
405: if (sourcePin instanceof Vertex) {
406: Vertex sourceVertex = (Vertex) sourcePin;
407: childExpr = createXPathRecursive(xPathModel,
408: sourceVertex);
409: } else if (sourcePin instanceof TreeSourcePin) {
410: TreePath sourceTreePath = ((TreeSourcePin) sourcePin)
411: .getTreePath();
412: TreePathInfo tpInfo = collectTreeInfo(sourceTreePath);
413: childExpr = createVariableXPath(xPathModel,
414: tpInfo);
415: }
416: }
417: //
418: if (childExpr != null) {
419: ((XPathOperationOrFuntion) newExpression)
420: .addChild(childExpr);
421: }
422: }
423: }
424: //
425: return newExpression;
426: }
427:
428: /**
429: * Creates XPath expression for the specified vertex.
430: *
431: * @param xPathModel
432: * @param vertex
433: * @return
434: */
435: protected XPathExpression createXPath(XPathModel xPathModel,
436: Vertex vertex) {
437: Object vertexDO = vertex.getDataObject();
438: XPathExpression result = null;
439: //
440: if (vertexDO instanceof CoreOperationType) {
441: CoreOperationType operType = (CoreOperationType) vertexDO;
442: result = xPathModel.getFactory().newXPathCoreOperation(
443: operType);
444: } else if (vertexDO instanceof CoreFunctionType) {
445: CoreFunctionType funcType = (CoreFunctionType) vertexDO;
446: result = xPathModel.getFactory().newXPathCoreFunction(
447: funcType);
448: } else if (vertexDO instanceof ExtFunctionMetadata) {
449: ExtFunctionMetadata funcMetadata = (ExtFunctionMetadata) vertexDO;
450: QName funcQName = funcMetadata.getName();
451: //
452: // Checks is there the prefix declaration and create it if necessary
453: String nsUri = funcQName.getNamespaceURI();
454: if (nsUri != null && nsUri.length() != 0) {
455: BpelModel bpelModel = getDesignContext().getBpelModel();
456: Process process = bpelModel.getProcess();
457: if (process != null) {
458: ExNamespaceContext nsContext = process
459: .getNamespaceContext();
460: try {
461: nsContext.addNamespace(nsUri);
462: } catch (InvalidNamespaceException ex) {
463: ErrorManager.getDefault().notify(ex);
464: return null;
465: }
466: }
467: }
468: //
469: result = xPathModel.getFactory().newXPathExtensionFunction(
470: funcQName);
471: } else if (vertex instanceof Constant) {
472: Constant constant = (Constant) vertex;
473: VertexItem firstVItem = constant.getItem(0);
474: String textValue = firstVItem.getText();
475: if (vertexDO == XPathStringLiteral.class) {
476: result = xPathModel.getFactory().newXPathStringLiteral(
477: textValue);
478: } else if (vertexDO == XPathNumericLiteral.class) {
479: try {
480: Integer literalValue = Integer.valueOf(textValue);
481: result = xPathModel.getFactory()
482: .newXPathNumericLiteral(literalValue);
483: } catch (NumberFormatException nfEx) {
484: // do nothing
485: }
486: //
487: if (result == null) {
488: try {
489: Double literalValue = Double.valueOf(textValue);
490: result = xPathModel.getFactory()
491: .newXPathNumericLiteral(literalValue);
492: } catch (NumberFormatException nfEx) {
493: // do nothing
494: }
495: }
496: //
497: if (result == null) {
498: try {
499: Float literalValue = Float.valueOf(textValue);
500: result = xPathModel.getFactory()
501: .newXPathNumericLiteral(literalValue);
502: } catch (NumberFormatException nfEx) {
503: // do nothing
504: }
505: }
506: }
507: }
508: //
509: return result;
510: }
511:
512: //==========================================================================
513:
514: /**
515: * Temporary container for collecting information about tree item.
516: */
517: protected class TreePathInfo {
518: public VariableDeclaration varDecl;
519: public Part part;
520: public ArrayList<Object> schemaCompList = new ArrayList<Object>();
521: public PartnerLink pLink;
522: public Roles roles;
523: }
524:
525: /**
526: * The object is a result of converting a Graph content to the XPath form
527: */
528: protected class XPathExprList {
529: private ArrayList<XPathExpression> mExprList;
530: // means that the first list item is connected to the right tree
531: private boolean mIsFirstConnected;
532:
533: public XPathExprList(ArrayList<XPathExpression> exprList,
534: boolean isFirstConnected) {
535: //
536: mExprList = exprList;
537: mIsFirstConnected = isFirstConnected;
538: }
539:
540: public XPathExpression getConnectedExpression() {
541: if (!mIsFirstConnected) {
542: return null;
543: } else {
544: return mExprList.get(0);
545: }
546: }
547:
548: @Override
549: public String toString() {
550: StringBuilder sb = new StringBuilder();
551: //
552: // The list of expressions can contain a few elements, but not more
553: // then one can be connected to the right tree. Only the first
554: // element, which are placed before the ";" delimiter is considered
555: // as connected. All others are detached.
556: //
557: boolean isFirst = mIsFirstConnected;
558: //
559: for (XPathExpression xPathExpr : mExprList) {
560: String exprString = xPathExpr.getExpressionString();
561: if (exprString != null && exprString.length() != 0) {
562: if (isFirst) {
563: isFirst = false;
564: } else {
565: sb
566: .append(XPathModelFactory.XPATH_EXPR_DELIMITER);
567: }
568: //
569: sb.append(exprString);
570: }
571: }
572: return sb.toString();
573: }
574:
575: }
576:
577: }
|