| /******************************************************************************* |
| * Copyright (c) 2005, 2012 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.bpel.ui.properties; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| |
| import javax.xml.namespace.QName; |
| |
| import org.eclipse.bpel.common.ui.details.IDetailsAreaConstants; |
| import org.eclipse.bpel.common.ui.flatui.FlatFormAttachment; |
| import org.eclipse.bpel.common.ui.flatui.FlatFormData; |
| import org.eclipse.bpel.model.Assign; |
| import org.eclipse.bpel.model.BPELFactory; |
| import org.eclipse.bpel.model.Copy; |
| import org.eclipse.bpel.model.From; |
| import org.eclipse.bpel.model.Query; |
| import org.eclipse.bpel.model.To; |
| import org.eclipse.bpel.model.Variable; |
| import org.eclipse.bpel.model.messageproperties.Property; |
| import org.eclipse.bpel.model.util.BPELConstants; |
| import org.eclipse.bpel.model.util.BPELUtils; |
| import org.eclipse.bpel.model.util.XSD2XMLGenerator; |
| import org.eclipse.bpel.ui.Messages; |
| import org.eclipse.bpel.ui.adapters.IVirtualCopyRuleSide; |
| import org.eclipse.bpel.ui.commands.InsertCopyCommand; |
| import org.eclipse.bpel.ui.details.providers.ModelTreeLabelProvider; |
| import org.eclipse.bpel.ui.details.providers.VariableTreeContentProvider; |
| import org.eclipse.bpel.ui.details.tree.ITreeNode; |
| import org.eclipse.bpel.ui.util.BPELUtil; |
| import org.eclipse.bpel.ui.util.XSDUtils; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.wst.wsdl.Message; |
| import org.eclipse.wst.wsdl.Part; |
| import org.eclipse.xsd.XSDAttributeDeclaration; |
| import org.eclipse.xsd.XSDElementDeclaration; |
| import org.eclipse.xsd.XSDNamedComponent; |
| import org.eclipse.xsd.XSDTypeDefinition; |
| import org.eclipse.xsd.impl.XSDTypeDefinitionImpl; |
| |
| /** |
| * An AssignCategory presenting a tree from which the user can select any of: - |
| * a Variable - a Part within a Variable - some XSD element within a Part within |
| * a Variable. |
| * |
| */ |
| |
| public class VariablePartAssignCategory extends AssignCategoryBase { |
| |
| Label fNameLabel; |
| Text fNameText; |
| Tree fVariableTree; |
| |
| TreeViewer fVariableViewer; |
| |
| VariableTreeContentProvider variableContentProvider; |
| Shell shell; |
| |
| protected VariablePartAssignCategory(BPELPropertySection anOwnerSection) { |
| super(anOwnerSection); |
| } |
| |
| /** |
| * @see org.eclipse.bpel.ui.properties.IAssignCategory#getName() |
| */ |
| @Override |
| public String getName() { |
| return Messages.VariablePartAssignCategory_Variable_or_Part_1; |
| } |
| |
| protected boolean isPropertyTree() { |
| return false; |
| } |
| |
| /** |
| * This is for XPath specific queries. |
| * |
| * TODO: Need to somehow externalized this for for non-XPath languages. |
| */ |
| |
| @SuppressWarnings("nls") |
| protected void updateQueryFieldFromTreeSelection() { |
| |
| if (displayQuery() == false || fChangeHelper.isNonUserChange() |
| || this.fModelObject == null || fModelObject.eContainer()==null) { |
| return; |
| } |
| |
| IStructuredSelection sel = (IStructuredSelection) fVariableViewer |
| .getSelection(); |
| Object[] path = variableContentProvider.getPathToRoot(sel |
| .getFirstElement()); |
| |
| StringBuilder builder = new StringBuilder(); |
| ArrayList<String> querySegments = new ArrayList<String>(); |
| |
| for (Object next : path) { |
| |
| Object eObj = BPELUtil.resolveXSDObject(BPELUtil.adapt(next, |
| ITreeNode.class).getModelObject()); |
| builder.setLength(0); |
| |
| String targetNamespace = null; |
| String namespacePrefix = null; |
| |
| if (eObj instanceof XSDAttributeDeclaration) { |
| |
| XSDAttributeDeclaration att = (XSDAttributeDeclaration) eObj; |
| targetNamespace = att.getTargetNamespace(); |
| builder.append("/@"); |
| |
| if (targetNamespace != null) { |
| |
| namespacePrefix = BPELUtil.lookupOrCreateNamespacePrefix( |
| fModelObject, targetNamespace, "xsd", shell); |
| if (namespacePrefix == null) { |
| break; |
| } |
| |
| builder.append(namespacePrefix).append(":"); |
| } |
| builder.append(att.getName()); |
| |
| } else if (eObj instanceof XSDElementDeclaration) { |
| |
| XSDElementDeclaration elm = (XSDElementDeclaration) eObj; |
| targetNamespace = elm.getTargetNamespace(); |
| int maxOccurs = XSDUtils.getMaxOccurs(elm); |
| |
| builder.append("/"); |
| if (targetNamespace != null) { |
| namespacePrefix = BPELUtil.lookupOrCreateNamespacePrefix( |
| fModelObject, targetNamespace, "xsd", shell); |
| if (namespacePrefix == null) { |
| break; |
| } |
| builder.append(namespacePrefix).append(":"); |
| } |
| |
| builder.append(elm.getName()); |
| // Unbounded or bounded by something higher then 1. |
| if (maxOccurs != 1) { |
| builder.append("[1]"); |
| } |
| } |
| |
| // If the current builder has length > 0, then there is a query |
| // segment for us to put in. |
| if (builder.length() > 0) { |
| querySegments.add(builder.toString()); |
| } |
| } |
| |
| Collections.reverse(querySegments); |
| builder.setLength(0); |
| for (String s : querySegments) { |
| builder.append(s); |
| } |
| |
| if (builder.length() > 0) { |
| builder.deleteCharAt(0); |
| } |
| |
| try { |
| fChangeHelper.startNonUserChange(); |
| |
| fNameText.setText(builder.toString()); |
| fNameText.setEnabled(true); |
| fNameLabel.setEnabled(true); |
| |
| } finally { |
| fChangeHelper.finishNonUserChange(); |
| } |
| } |
| |
| @Override |
| protected void createClient2(Composite parent) { |
| |
| FlatFormData data; |
| |
| fVariableTree = fWidgetFactory |
| .createTree(parent, SWT.NONE /* SWT.BORDER */); |
| |
| if (displayQuery()) { |
| // area for query string and wizard button |
| fNameLabel = fWidgetFactory.createLabel(parent, |
| Messages.VariablePartAssignCategory_Query__8); |
| fNameText = fWidgetFactory.createText(parent, ""); //$NON-NLS-1$ |
| data = new FlatFormData(); |
| data.left = new FlatFormAttachment(0, BPELUtil.calculateLabelWidth( |
| fNameText, STANDARD_LABEL_WIDTH_SM)); |
| data.right = new FlatFormAttachment(100, |
| -IDetailsAreaConstants.HSPACE); |
| data.bottom = new FlatFormAttachment(100, 0); |
| |
| data.top = new FlatFormAttachment(100, (-1) |
| * (fNameText.getLineHeight() + 4 * fNameText |
| .getBorderWidth()) - IDetailsAreaConstants.VSPACE); |
| fNameText.setLayoutData(data); |
| |
| fChangeHelper.startListeningTo(fNameText); |
| fChangeHelper.startListeningForEnter(fNameText); |
| |
| data = new FlatFormData(); |
| data.left = new FlatFormAttachment(0, 0); |
| data.right = new FlatFormAttachment(fNameText, |
| -IDetailsAreaConstants.HSPACE); |
| data.top = new FlatFormAttachment(fNameText, 0, SWT.CENTER); |
| fNameLabel.setLayoutData(data); |
| } |
| |
| data = new FlatFormData(); |
| data.left = new FlatFormAttachment(0, 0); |
| data.top = new FlatFormAttachment(0, 0); |
| data.right = new FlatFormAttachment(100, 0); |
| if (displayQuery()) { |
| data.bottom = new FlatFormAttachment(fNameText, |
| -IDetailsAreaConstants.VSPACE, SWT.TOP); |
| } else { |
| data.bottom = new FlatFormAttachment(100, 0); |
| } |
| |
| // data.borderType = IBorderConstants.BORDER_2P2_BLACK; |
| fVariableTree.setLayoutData(data); |
| |
| variableContentProvider = new VariableTreeContentProvider(true, |
| isPropertyTree(), displayQuery()); |
| fVariableViewer = new TreeViewer(fVariableTree); |
| fVariableViewer.setContentProvider(variableContentProvider); |
| fVariableViewer.setLabelProvider(new ModelTreeLabelProvider()); |
| // TODO: does this sorter work at the top level? does it affect nested |
| // levels too? |
| // variableViewer.setSorter(ModelViewerSorter.getInstance()); |
| fVariableViewer.setInput(fOwnerSection.getModel()); |
| |
| fVariableViewer |
| .addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| updateQueryFieldFromTreeSelection(); |
| } |
| }); |
| |
| fChangeHelper.startListeningTo(fVariableTree); |
| } |
| |
| /** |
| * @see org.eclipse.bpel.ui.properties.IAssignCategory#isCategoryForModel(org.eclipse.emf.ecore.EObject) |
| */ |
| |
| @Override |
| public boolean isCategoryForModel(EObject aModel) { |
| |
| if (aModel == null) { |
| return false; |
| } |
| IVirtualCopyRuleSide side = BPELUtil.adapt(aModel, |
| IVirtualCopyRuleSide.class); |
| if (side == null) { |
| return false; |
| } |
| return side.getVariable() != null |
| && (side.getProperty() != null) == isPropertyTree(); |
| } |
| |
| @SuppressWarnings("nls") |
| @Override |
| protected void load(IVirtualCopyRuleSide side) { |
| |
| fChangeHelper.startNonUserChange(); |
| try { |
| fVariableViewer.setSelection(StructuredSelection.EMPTY, false); |
| if (displayQuery()) { |
| fNameText.setText(EMPTY_STRING); |
| fNameText.setEnabled(true); |
| fNameLabel.setEnabled(true); |
| } |
| } finally { |
| fChangeHelper.finishNonUserChange(); |
| } |
| |
| ArrayList<ITreeNode> pathToNode = new ArrayList<ITreeNode>(); |
| ITreeNode node = null; |
| |
| // First, find the variable node. |
| Object context = side.getVariable(); |
| if (context != null) { |
| |
| Object[] items = variableContentProvider |
| .getElements(fVariableViewer.getInput()); |
| node = variableContentProvider.findModelNode(items, context, 0); |
| if (node != null) { |
| pathToNode.add(node); |
| } |
| } |
| |
| // Find the part (or property) node within the container node. |
| if (isPropertyTree()) { |
| context = side.getProperty(); |
| } else { |
| context = side.getPart(); |
| } |
| |
| if (node != null && context != null) { |
| Object[] items = variableContentProvider.getChildren(node); |
| node = variableContentProvider.findModelNode(items, context, |
| variableContentProvider.isCondensed() ? 0 : 1); |
| if (node != null) { |
| pathToNode.add(node); |
| } |
| } |
| |
| if (context == null) { |
| context = side.getVariable(); |
| } |
| |
| String query = null; |
| |
| if (node != null && context != null) { |
| |
| Query queryObject = side.getQuery(); |
| if (queryObject != null) { |
| // TODO: we shouldn't ignore the queryLanguage here!! |
| query = queryObject.getValue(); |
| } |
| |
| if (query != null && !query.equals(EMPTY_STRING)) { |
| |
| int tokenCount = 0; |
| outer: for (String token : query.split("\\/")) { |
| tokenCount += 1; |
| if (token.length() == 0) { |
| // Is it the first empty string preceeding the first / |
| if (tokenCount == 1) { |
| continue; |
| } |
| // could be // , as in //foo:bar/bar, which is |
| // impossible to show here. |
| break outer; |
| } |
| |
| QueryStep step = new QueryStep(token); |
| step.updateNamespaceURI(this.fModelObject); |
| |
| if (step.fAxis.equals("child") == false) { |
| break outer; |
| } |
| |
| Object[] items = variableContentProvider.getChildren(node); |
| |
| inner: for (Object item : items) { |
| |
| Object originalMatch = ((ITreeNode) item) |
| .getModelObject(); |
| Object match = BPELUtil.resolveXSDObject(originalMatch); |
| |
| if (match instanceof XSDElementDeclaration) { |
| XSDElementDeclaration elmDecl = (XSDElementDeclaration) match; |
| |
| if (match(step, elmDecl) == false) { |
| continue; |
| } |
| node = variableContentProvider.findModelNode(items, |
| originalMatch, 0); |
| // no matching node, we are done |
| if (node == null) { |
| break outer; |
| } |
| pathToNode.add(node); |
| break inner; |
| |
| } else if (match instanceof XSDAttributeDeclaration) { |
| |
| XSDAttributeDeclaration attrDecl = (XSDAttributeDeclaration) match; |
| if (match(step, attrDecl)) { |
| node = variableContentProvider.findModelNode( |
| items, originalMatch, 0); |
| if (node != null) { |
| pathToNode.add(node); |
| } |
| } |
| // attribute is the leaf node |
| break outer; |
| } |
| } |
| } |
| } |
| } |
| |
| if (pathToNode.size() > 0) { |
| node = pathToNode.get(pathToNode.size() - 1); |
| } |
| |
| if (node != null) { |
| |
| fChangeHelper.startNonUserChange(); |
| try { |
| if (displayQuery()) { |
| fNameText.setText(query == null ? EMPTY_STRING : query); |
| } |
| fVariableViewer.expandToLevel(node, 0); |
| fVariableViewer.setSelection(new StructuredSelection(node), |
| true); |
| } finally { |
| fChangeHelper.finishNonUserChange(); |
| } |
| |
| } |
| } |
| |
| boolean match(QueryStep step, XSDNamedComponent xsdNamed) { |
| // local name |
| if (step.fLocalPart.equals(xsdNamed.getName()) == false) { |
| return false; |
| } |
| |
| // namespace |
| return (step.fNamespaceURI.equals(xsdNamed.getTargetNamespace()) || (step.fNamespaceURI |
| .equals(EMPTY_STRING) && xsdNamed.getTargetNamespace() == null)); |
| } |
| |
| @Override |
| protected void store(IVirtualCopyRuleSide side) { |
| IStructuredSelection sel = (IStructuredSelection) fVariableViewer |
| .getSelection(); |
| |
| Object[] path = variableContentProvider.getPathToRoot(sel |
| .getFirstElement()); |
| String query = displayQuery() ? fNameText.getText() : EMPTY_STRING; |
| |
| side.setVariable(null); |
| side.setPart(null); |
| side.setProperty(null); |
| side.setQuery(null); |
| |
| for (Object n : path) { |
| ITreeNode treeNode = BPELUtil.adapt(n, ITreeNode.class); |
| |
| Object model = treeNode.getModelObject(); |
| if (model instanceof Variable) { |
| side.setVariable((Variable) model); |
| } |
| if (model instanceof Part) { |
| side.setPart((Part) model); |
| } |
| if (model instanceof Property) { |
| side.setProperty((Property) model); |
| } |
| } |
| |
| query = query.trim(); |
| if (displayQuery() && query.length() > 0) { |
| Query queryObject = BPELFactory.eINSTANCE.createQuery(); |
| queryObject |
| .setQueryLanguage(BPELConstants.XMLNS_XPATH_QUERY_LANGUAGE); |
| queryObject.setValue(query); |
| side.setQuery(queryObject); |
| } else { |
| side.setQuery(null); |
| } |
| |
| // https://jira.jboss.org/browse/JBIDE-7351 |
| // TODO: Think about how to implement this in a way that makes sense... |
| // currently, a popup dialog asks the user to initialize variables whenever |
| // focus changes - this makes for a bad user experience! |
| // From? |
| if (side.isSource()) |
| return; |
| |
| // if initializer doesn't exist and query != null then we should |
| // generate it |
| if (query == null) |
| return; |
| Variable var = side.getVariable(); |
| if (needInitializer(var, side)) { |
| if (MessageDialog |
| .openQuestion( |
| PlatformUI.getWorkbench().getActiveWorkbenchWindow() |
| .getShell(), |
| "Initializer", |
| NLS |
| .bind( |
| "Variable {0} doesn't have initializer. Should it be generated?", |
| (new Object[] { var.getName() })))) { |
| initTargetVariable(var, side); |
| } |
| } |
| } |
| |
| private boolean needInitializer(Variable var, IVirtualCopyRuleSide side) { |
| Assign a = (Assign) ((To) side.getCopyRuleSide()).getContainer() |
| .getContainer(); |
| EList<Copy> list = a.getCopy(); |
| for (Copy copy : list) { |
| if (copy.getFrom().getLiteral() == null) |
| continue; |
| To to = copy.getTo(); |
| Variable v = to.getVariable(); |
| if (v == null) |
| continue; |
| if (!v.equals(var)) |
| continue; |
| Part p = to.getPart(); |
| if (p == null) |
| continue; |
| if (p.equals(side.getPart())) |
| return false; |
| } |
| |
| // https://issues.jboss.org/browse/JBIDE-8048 |
| // check if initialization is possible: this is not possible if the |
| // variable is implicit (e.g. in a ForEach or OnEvent) |
| String rootElement = null; |
| String uriWSDL = null; |
| |
| // Variable is defined using "messageType" |
| Message msg = var.getMessageType(); |
| if (msg != null && !msg.eIsProxy()) { |
| // https://jira.jboss.org/browse/JBIDE-6697 |
| // from eclipse.org/bpel rev 1.17 on 7/23/2010 3:13AM bugzilla 302943 by gqian: apply the patch from bugzilla |
| if (side.getPart() != null) { |
| XSDElementDeclaration declaration = side.getPart().getElementDeclaration(); |
| if (declaration != null) { |
| uriWSDL = declaration.getSchema().getSchemaLocation(); |
| rootElement = declaration.getName(); |
| } |
| } |
| } |
| |
| // can we construct an initializer for this variable? |
| // Variable is defined using "type" |
| XSDTypeDefinitionImpl type = (XSDTypeDefinitionImpl)var.getType(); |
| if (type != null && !type.eIsProxy()) { |
| QName qname = new QName(type.getTargetNamespace(), type.getName()); |
| rootElement = qname.getLocalPart(); |
| uriWSDL = type.eResource().getURI().toString(); |
| } |
| |
| // Variable is defined using "element" |
| XSDElementDeclaration element = var.getXSDElement(); |
| if (element != null && !element.eIsProxy()) { |
| QName qname = new QName(element.getTargetNamespace(), element |
| .getName()); |
| rootElement = qname.getLocalPart(); |
| uriWSDL = element.eResource().getURI().toString(); |
| } |
| |
| // Incomplete variable definition |
| if (rootElement == null || uriWSDL == null) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| private void initTargetVariable(Variable var, IVirtualCopyRuleSide side) { |
| String rootElement = null; |
| String uriWSDL = null; |
| |
| // Variable is defined using "messageType" |
| Message msg = var.getMessageType(); |
| if (msg != null) { |
| // https://jira.jboss.org/browse/JBIDE-6697 |
| // from eclipse.org/bpel rev 1.17 on 7/23/2010 3:13AM bugzilla 302943 by gqian: apply the patch from bugzilla |
| if (side.getPart() != null) { |
| XSDElementDeclaration declaration = side.getPart().getElementDeclaration(); |
| if (declaration != null) { |
| uriWSDL = declaration.getSchema().getSchemaLocation(); |
| rootElement = declaration.getName(); |
| } |
| } |
| } |
| |
| // Variable is defined using "type" |
| XSDTypeDefinition type = var.getType(); |
| if (type != null) { |
| QName qname = new QName(type.getTargetNamespace(), type.getName()); |
| rootElement = qname.getLocalPart(); |
| uriWSDL = type.eResource().getURI().toString(); |
| } |
| |
| // Variable is defined using "element" |
| XSDElementDeclaration element = var.getXSDElement(); |
| if (element != null) { |
| QName qname = new QName(element.getTargetNamespace(), element |
| .getName()); |
| rootElement = qname.getLocalPart(); |
| uriWSDL = element.eResource().getURI().toString(); |
| } |
| |
| // Incomplete variable definition |
| if (rootElement == null || uriWSDL == null) { |
| return; |
| } |
| |
| // https://jira.jboss.org/browse/JBIDE-7351 |
| // use the new and improved XSD -> XML generator |
| // this was an internal class that was moved to org.eclipse.bpel.model.util |
| XSD2XMLGenerator generator = new XSD2XMLGenerator(uriWSDL, rootElement); |
| |
| // be sure to tell the generator which elements in a "choice" we are interested in |
| if (side.getQuery()!=null && side.getQuery().getValue().trim().length()>0) |
| generator.setQueryPath(side.getQuery().getValue()); |
| |
| try { |
| String literal = generator.createXML(); |
| Copy copy = BPELFactory.eINSTANCE.createCopy(); |
| Assign a = (Assign) ((To) side.getCopyRuleSide()).getContainer() |
| .getContainer(); |
| getCommandFramework() |
| .execute( |
| wrapInShowContextCommand(new InsertCopyCommand(a, |
| copy, 0))); |
| To to = BPELFactory.eINSTANCE.createTo(); |
| From from = BPELFactory.eINSTANCE.createFrom(); |
| from.setLiteral(literal); |
| copy.setFrom(from); |
| to.setVariable(side.getVariable()); |
| to.setPart(side.getPart()); |
| copy.setTo(to); |
| fChangeHelper.startNonUserChange(); |
| fOwnerSection.basicSetInput(a); |
| fChangeHelper.finishNonUserChange(); |
| } catch (Exception e) { |
| throw new IllegalStateException( |
| "Can't generate initializer, check WSDL file"); |
| } |
| } |
| |
| @Override |
| protected void basicSetInput(EObject newInput) { |
| |
| super.basicSetInput(newInput); |
| |
| /** |
| * During initialization of variable, the list of available variables |
| * must not include the current variable and the variables logically |
| * after. So we just alter the input to the variable viewer, if we are |
| * looking at a variable. In assign statement, where the model is Copy, |
| * this does not happen. |
| */ |
| |
| EObject container = newInput.eContainer(); |
| if (container instanceof Variable) { |
| |
| fChangeHelper.startNonUserChange(); |
| try { |
| fVariableViewer.setInput(container); |
| } finally { |
| fChangeHelper.finishNonUserChange(); |
| } |
| } |
| } |
| |
| /** |
| * @see org.eclipse.bpel.ui.properties.BPELPropertySection#getUserContext() |
| */ |
| @Override |
| public Object getUserContext() { |
| return null; |
| } |
| |
| /** |
| * @see org.eclipse.bpel.ui.properties.BPELPropertySection#restoreUserContext(java.lang.Object) |
| */ |
| @Override |
| public void restoreUserContext(Object userContext) { |
| fVariableTree.setFocus(); |
| } |
| |
| private boolean displayQuery() { |
| return !isPropertyTree(); |
| } |
| |
| /** |
| * Parse the query step into this object. |
| * |
| * TODO: This has to be externalized someplace. We can't just assume it is |
| * XPath all the time ... |
| */ |
| |
| @SuppressWarnings("nls") |
| class QueryStep { |
| |
| String fAxis = "child"; |
| |
| String fPrefix = EMPTY_STRING; |
| String fLocalPart = EMPTY_STRING; |
| String fNamespaceURI = EMPTY_STRING; |
| |
| @SuppressWarnings("nls") |
| QueryStep(String step) { |
| |
| int axisMark = step.indexOf("::"); |
| if (axisMark >= 0) { |
| fAxis = step.substring(0, axisMark); |
| step = step.substring(axisMark + 2); |
| } |
| |
| int qnameMark = step.indexOf(":"); |
| if (qnameMark < 0) { |
| fLocalPart = step; |
| } else { |
| fLocalPart = step.substring(qnameMark + 1); |
| fPrefix = step.substring(0, qnameMark); |
| } |
| |
| if (fLocalPart.charAt(0) == '@') { |
| fLocalPart = fLocalPart.substring(1); |
| } |
| |
| int arrayMark1 = fLocalPart.indexOf('['); |
| int arrayMark2 = fLocalPart.indexOf(']'); |
| if (arrayMark2 > arrayMark1 && arrayMark1 > 0) { |
| fLocalPart = fLocalPart.substring(0, arrayMark1); |
| } |
| } |
| |
| void updateNamespaceURI(EObject eObj) { |
| if (fPrefix.length() > 0) { |
| fNamespaceURI = BPELUtils.getNamespace(eObj, fPrefix); |
| if (fNamespaceURI == null) { |
| fNamespaceURI = "urn:unresolved:" |
| + System.currentTimeMillis() + ":" + fPrefix; |
| } |
| } else { |
| fNamespaceURI = EMPTY_STRING; |
| } |
| } |
| |
| } |
| } |