blob: de35b15e59f5531b65a7b95ee666e7ec97e7d4fe [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2012 Intel Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dennis Ushakov, Intel
* Oleg Danilov, Intel
*
*******************************************************************************/
package org.eclipse.bpel.ui;
import org.eclipse.bpel.model.Process;
import org.eclipse.bpel.model.adapters.INamespaceMap;
import org.eclipse.bpel.model.impl.BPELExtensibilityElementImpl;
import org.eclipse.bpel.model.BPELExtensibleElement;
import org.eclipse.bpel.model.util.BPELConstants;
import org.eclipse.bpel.model.util.BPELUtils;
import org.eclipse.bpel.ui.util.BPELEditorUtil;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.wsdl.internal.impl.WSDLElementImpl;
import org.eclipse.wst.wsdl.internal.impl.XSDSchemaExtensibilityElementImpl;
import org.eclipse.wst.xsd.ui.internal.util.ModelReconcileAdapter;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.impl.XSDSchemaImpl;
import org.eclipse.xsd.util.XSDConstants;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
class BPELModelReconcileAdapter extends ModelReconcileAdapter {
protected Process process;
protected Resource bpelResource;
private BPELEditor fEditor;
public BPELModelReconcileAdapter(Document document, Process process,
Resource bpelResource, BPELEditor editor) {
super(document);
this.process = process;
this.bpelResource = bpelResource;
this.fEditor = editor;
}
// This method is clever enough to deal with 'bad' documents that happen
// to have more than one root element. It picks of the first 'matching'
// element.
private Element getProcessElement(Document document) {
Element processElement = null;
for (Node node = document.getFirstChild(); node != null; node = node
.getNextSibling()) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
if (BPELEditorUtil.getInstance().getBPELType(element).equals(
BPELConstants.ND_PROCESS)) {
processElement = element;
break;
}
}
}
return processElement;
}
@Override
protected void handleNodeChanged(Node node) {
if (node instanceof Element
&& !BPELConstants.ND_LITERAL.equals(node.getLocalName())) {
reconcileModelObjectForElement((Element) node);
} else if (node instanceof Document) {
Document document = (Document) node;
Element processElement = getProcessElement(document);
if (processElement != null
&& process.getElement() != processElement) {
process.setElement(processElement);
} else if (processElement != null) {
process.elementChanged(processElement);
} else {
process.setPartnerLinks(null);
process.setVariables(null);
process.setCorrelationSets(null);
process.setActivity(null);
process.setDocumentation(null);
process.setName(null);
process.setTargetNamespace(null);
process.unsetQueryLanguage();
process.unsetExpressionLanguage();
process.unsetSuppressJoinFailure();
process.unsetVariableAccessSerializable();
process.unsetAbstractProcessProfile();
process.setFaultHandlers(null);
process.setExtensions(null);
process.setExitOnStandardFault(false);
process.setMessageExchanges(null);
process.setEventHandlers(null);
if (processElement != null) {
process.setElement(processElement);
process.elementChanged(processElement);
}
}
} else if (node.getNodeType() == Node.CDATA_SECTION_NODE
|| BPELConstants.ND_LITERAL.equals(node.getLocalName())) {
reconcileModelObjectForElement((Element) node.getParentNode());
}
}
private void reconcileModelObjectForElement(Element elementCandidate) {
Object modelObjectCandidate = BPELEditorUtil.getInstance()
.findModelObjectForElement(process, elementCandidate);
// Get out of possible nested XML within the literal
while (modelObjectCandidate == null
&& elementCandidate.getParentNode() != null) {
elementCandidate = (Element) elementCandidate.getParentNode();
modelObjectCandidate = BPELEditorUtil.getInstance()
.findModelObjectForElement(process, elementCandidate);
}
// Wrap changes in source tab to the Command
if (modelObjectCandidate != null) {
final Object modelObject = modelObjectCandidate;
final Element element = elementCandidate;
// UpdateModelCommand cmd = new UpdateModelCommand(
// (EObject) modelObject, "Change text") {
// @SuppressWarnings("restriction")
// @Override
// public void doExecute() {
if (modelObject instanceof BPELExtensibleElement) {
((BPELExtensibleElement) modelObject)
.elementChanged(element);
// https://jira.jboss.org/browse/JBIDE-7497
// Bugzilla 330519
this.fEditor.getMultipageEditor().updateMarkers((BPELExtensibleElement)modelObject);
} else if (modelObject instanceof BPELExtensibilityElementImpl) {
((BPELExtensibilityElementImpl) modelObject)
.elementChanged(element);
} else if (modelObject instanceof XSDSchemaExtensibilityElementImpl) {
XSDSchemaExtensibilityElementImpl ee = (XSDSchemaExtensibilityElementImpl) modelObject;
((XSDSchemaImpl) ee.getSchema())
.elementChanged(element);
ee.elementChanged(element);
} else if (modelObject instanceof WSDLElementImpl) {
((WSDLElementImpl) modelObject).elementChanged(element);
} else if (modelObject instanceof XSDConcreteComponent) {
((XSDConcreteComponent) modelObject)
.elementChanged(element);
}
// }
// };
// fEditor.getCommandFramework().execute(cmd);
}
}
@Override
public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
if (!isDirty) {
// cs : At this time (when a save occurs) it's a good opportunity
// to update the model to ensure it's in sync with the source.
// That way if the incremental sync between DOM and model has gotten
// the model out of whack we'll be able to put things right at this
// point.
//
// TODO (cs) need to do more to ensure model is sync'd up properly
// FIXME uncomment
// ((ProcessImpl)process).reconcileReferences(true);
}
}
@Override
public void handleNotifyChange(INodeNotifier notifier, int eventType,
final Object feature, final Object oldValue, final Object newValue,
int index) {
final Node node = (Node) notifier;
switch (eventType) {
case INodeNotifier.ADD: {
if (newValue instanceof Element) {
Element element = (Element) newValue;
adapt(element);
}
break;
}
case INodeNotifier.REMOVE: {
break;
}
case INodeNotifier.CHANGE:
case INodeNotifier.STRUCTURE_CHANGED: {
if (feature instanceof Attr
&& XSDConstants.XMLNS_URI_2000.equals(((Attr) feature)
.getNamespaceURI())) {
final Attr attr = (Attr) feature;
final EObject modelObject = (EObject) BPELEditorUtil
.getInstance().findModelObjectForElement(process,
(Element) node);
final INamespaceMap<String, String> objectMap = BPELUtils
.getNamespaceMap(modelObject);
// UpdateModelCommand cmd = new UpdateModelCommand(modelObject,
// "Change text") {
// @SuppressWarnings("restriction")
// @Override
// public void doExecute() {
if (newValue == null) {
objectMap.remove(BPELUtils.getNSPrefixMapKey(attr
.getLocalName()));
} else {
objectMap.put(BPELUtils.getNSPrefixMapKey(attr
.getLocalName()), attr.getValue());
}
// }
// };
// if (fEditor != null) {
// fEditor.getCommandFramework().execute(cmd);
// }
// We should continue reconciling only if BPEL namespace has
// been changed
// otherwise we should not update children
if (!BPELConstants.NAMESPACE.equals(attr.getValue()))
break;
}
handleNodeChanged(node);
break;
}
case INodeNotifier.CONTENT_CHANGED: {
handleNodeChanged(node);
break;
}
}
}
}