diff options
Diffstat (limited to 'org.eclipse.m2e.model.edit/src/main/java/org/eclipse/m2e/model/edit/pom/translators/ModelObjectAdapter.java')
-rw-r--r-- | org.eclipse.m2e.model.edit/src/main/java/org/eclipse/m2e/model/edit/pom/translators/ModelObjectAdapter.java | 547 |
1 files changed, 261 insertions, 286 deletions
diff --git a/org.eclipse.m2e.model.edit/src/main/java/org/eclipse/m2e/model/edit/pom/translators/ModelObjectAdapter.java b/org.eclipse.m2e.model.edit/src/main/java/org/eclipse/m2e/model/edit/pom/translators/ModelObjectAdapter.java index eab5cb15..9395c9ce 100644 --- a/org.eclipse.m2e.model.edit/src/main/java/org/eclipse/m2e/model/edit/pom/translators/ModelObjectAdapter.java +++ b/org.eclipse.m2e.model.edit/src/main/java/org/eclipse/m2e/model/edit/pom/translators/ModelObjectAdapter.java @@ -16,6 +16,10 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; @@ -23,304 +27,275 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter; +import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement; + import org.eclipse.m2e.model.edit.pom.Configuration; import org.eclipse.m2e.model.edit.pom.PomFactory; import org.eclipse.m2e.model.edit.pom.PomPackage; import org.eclipse.m2e.model.edit.pom.PropertyElement; -import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter; -import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; + /** - * Listens for notifications from the dom model and the E model, and syncs the - * models. + * Listens for notifications from the dom model and the E model, and syncs the models. * * @author Mike Poindexter */ -public class ModelObjectAdapter extends TranslatorAdapter implements Adapter, - INodeAdapter { - private SSESyncResource resource; - - private EObject eobject; - - private Notifier target; - - private Map<EStructuralFeature, TranslatorAdapter> childAdapters = new LinkedHashMap<EStructuralFeature, TranslatorAdapter>(); - - public ModelObjectAdapter(SSESyncResource resource, EObject eobject, - Element node) { - super(resource); - this.eobject = eobject; - this.node = node; - this.resource = resource; - } - - public boolean isAdapterForType(Object type) { - return ModelObjectAdapter.class.equals(type); - } - - public void notifyChanged(INodeNotifier notifier, int eventType, - Object changedFeature, Object oldValue, Object newValue, int pos) { - if (resource.isProcessEvents()) { - resource.setProcessEvents(false); - try { - if (INodeNotifier.ADD == eventType - && newValue instanceof Element) { - if (notifier == node) { - IDOMElement addedElement = (IDOMElement) newValue; - EStructuralFeature feature = eobject.eClass() - .getEStructuralFeature( - addedElement.getLocalName()); - if (feature != null) { - createOrGetChildAdapter(feature).load(); - } - } - } else if (INodeNotifier.REMOVE == eventType - && oldValue instanceof Element) { - if (notifier == node) { - IDOMElement removedElement = (IDOMElement) oldValue; - EStructuralFeature feature = eobject.eClass() - .getEStructuralFeature( - removedElement.getLocalName()); - if (feature != null) { - eobject.eUnset(feature); - childAdapters.remove(feature); - } - } - } - } finally { - resource.setProcessEvents(true); - } - } - } - - public void notifyChanged(Notification notification) { - if (resource.isProcessEvents()) { - resource.setProcessEvents(false); - try { - EStructuralFeature feature = (EStructuralFeature) notification - .getFeature(); - switch (notification.getEventType()) { - - case Notification.SET: - if (null == notification.getNewValue() - || "".equals(notification.getNewValue())) { //$NON-NLS-1$ - removeDomChild(feature); - } else { - TranslatorAdapter setAdapter = createOrGetChildAdapter(feature); - setAdapter.update(notification.getOldValue(), - notification.getNewValue(), notification - .getPosition()); - } - - break; - - case Notification.ADD: - ListAdapter addListAdapter = (ListAdapter) createOrGetChildAdapter(feature); - addListAdapter.add(notification.getNewValue(), notification - .getPosition()); - break; - - case Notification.ADD_MANY: - ListAdapter addManyListAdapter = (ListAdapter) createOrGetChildAdapter(feature); - Collection<?> addMany = (Collection<?>) notification - .getNewValue(); - int addPosition = notification.getPosition(); - int addIdx = addPosition; - for (Object object : addMany) { - addManyListAdapter - .add( - object, - addPosition == Notification.NO_INDEX ? Notification.NO_INDEX - : addIdx); - addIdx++; - } - break; - - case Notification.REMOVE: - ListAdapter removeListAdapter = (ListAdapter) createOrGetChildAdapter(feature); - removeListAdapter.remove(notification.getOldValue(), - notification.getPosition()); - break; - - case Notification.UNSET: - removeDomChild(feature); - break; - - case Notification.REMOVE_MANY: - ListAdapter removeManyListAdapter = (ListAdapter) createOrGetChildAdapter(feature); - Collection<?> removeMany = (Collection<?>) notification - .getOldValue(); - int removePosition = notification.getPosition(); - int removeIdx = removePosition; - for (Object object : removeMany) { - removeManyListAdapter - .remove( - object, - removePosition == Notification.NO_INDEX ? Notification.NO_INDEX - : removeIdx); - removeIdx++; - } - break; - - } - } finally { - resource.setProcessEvents(true); - } - } - - } - - @Override - public void update(Object oldValue, Object newValObject, int index) { - save(); - } - - private TranslatorAdapter createOrGetChildAdapter(EStructuralFeature feature) { - TranslatorAdapter ret = childAdapters.get(feature); - if (null == ret) { - Element element = getFirstChildWithName(node, feature.getName()); - boolean isNew = false; - if (element == null) { - element = node.getOwnerDocument().createElement(feature.getName()); - insertElement(element); - isNew = true; - } - - if (feature.isMany()) { - EClass elementType = null; - if (feature instanceof EReference) { - elementType = ((EReference) feature).getEReferenceType(); - } - - if (elementType != null && elementType.getClassifierID() == PomPackage.Literals.PROPERTY_ELEMENT.getClassifierID()) { - ret = new PropertiesAdapter(resource, element, (List<PropertyElement>) eobject.eGet(feature)); - } else { - ret = new ListAdapter(resource, element, (List<?>) eobject.eGet(feature), elementType); - } - } else if (feature instanceof EReference) { - EReference ref = (EReference) feature; - EObject eo = (EObject) eobject.eGet(feature); - if (null == eo) { - eo = PomFactory.eINSTANCE.create(ref.getEReferenceType()); - eobject.eSet(ref, eo); - } - - EClass elementType = ref.getEReferenceType(); - if (elementType != null && elementType.getClassifierID() == PomPackage.Literals.CONFIGURATION.getClassifierID()) { - ret = new ConfigurationAdapter(resource, element, (Configuration)eobject.eGet(feature)); +public class ModelObjectAdapter extends TranslatorAdapter implements Adapter, INodeAdapter { + private SSESyncResource resource; + + private EObject eobject; + + private Notifier target; + + private Map<EStructuralFeature, TranslatorAdapter> childAdapters = new LinkedHashMap<EStructuralFeature, TranslatorAdapter>(); + + public ModelObjectAdapter(SSESyncResource resource, EObject eobject, Element node) { + super(resource); + this.eobject = eobject; + this.node = node; + this.resource = resource; + } + + public boolean isAdapterForType(Object type) { + return ModelObjectAdapter.class.equals(type); + } + + public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, + Object newValue, int pos) { + if(resource.isProcessEvents()) { + resource.setProcessEvents(false); + try { + if(INodeNotifier.ADD == eventType && newValue instanceof Element) { + if(notifier == node) { + IDOMElement addedElement = (IDOMElement) newValue; + EStructuralFeature feature = eobject.eClass().getEStructuralFeature(addedElement.getLocalName()); + if(feature != null) { + createOrGetChildAdapter(feature).load(); + } + } + } else if(INodeNotifier.REMOVE == eventType && oldValue instanceof Element) { + if(notifier == node) { + IDOMElement removedElement = (IDOMElement) oldValue; + EStructuralFeature feature = eobject.eClass().getEStructuralFeature(removedElement.getLocalName()); + if(feature != null) { + eobject.eUnset(feature); + childAdapters.remove(feature); + } + } + } + } finally { + resource.setProcessEvents(true); + } + } + } + + public void notifyChanged(Notification notification) { + if(resource.isProcessEvents()) { + resource.setProcessEvents(false); + try { + EStructuralFeature feature = (EStructuralFeature) notification.getFeature(); + switch(notification.getEventType()) { + + case Notification.SET: + if(null == notification.getNewValue() || "".equals(notification.getNewValue())) { //$NON-NLS-1$ + removeDomChild(feature); + } else { + TranslatorAdapter setAdapter = createOrGetChildAdapter(feature); + setAdapter.update(notification.getOldValue(), notification.getNewValue(), notification.getPosition()); + } + + break; + + case Notification.ADD: + ListAdapter addListAdapter = (ListAdapter) createOrGetChildAdapter(feature); + addListAdapter.add(notification.getNewValue(), notification.getPosition()); + break; + + case Notification.ADD_MANY: + ListAdapter addManyListAdapter = (ListAdapter) createOrGetChildAdapter(feature); + Collection<?> addMany = (Collection<?>) notification.getNewValue(); + int addPosition = notification.getPosition(); + int addIdx = addPosition; + for(Object object : addMany) { + addManyListAdapter.add(object, addPosition == Notification.NO_INDEX ? Notification.NO_INDEX : addIdx); + addIdx++ ; + } + break; + + case Notification.REMOVE: + ListAdapter removeListAdapter = (ListAdapter) createOrGetChildAdapter(feature); + removeListAdapter.remove(notification.getOldValue(), notification.getPosition()); + break; + + case Notification.UNSET: + removeDomChild(feature); + break; + + case Notification.REMOVE_MANY: + ListAdapter removeManyListAdapter = (ListAdapter) createOrGetChildAdapter(feature); + Collection<?> removeMany = (Collection<?>) notification.getOldValue(); + int removePosition = notification.getPosition(); + int removeIdx = removePosition; + for(Object object : removeMany) { + removeManyListAdapter.remove(object, removePosition == Notification.NO_INDEX ? Notification.NO_INDEX + : removeIdx); + removeIdx++ ; + } + break; + + } + } finally { + resource.setProcessEvents(true); + } + } + + } + + @Override + public void update(Object oldValue, Object newValObject, int index) { + save(); + } + + private TranslatorAdapter createOrGetChildAdapter(EStructuralFeature feature) { + TranslatorAdapter ret = childAdapters.get(feature); + if(null == ret) { + Element element = getFirstChildWithName(node, feature.getName()); + boolean isNew = false; + if(element == null) { + element = node.getOwnerDocument().createElement(feature.getName()); + insertElement(element); + isNew = true; + } + + if(feature.isMany()) { + EClass elementType = null; + if(feature instanceof EReference) { + elementType = ((EReference) feature).getEReferenceType(); + } + + if(elementType != null + && elementType.getClassifierID() == PomPackage.Literals.PROPERTY_ELEMENT.getClassifierID()) { + ret = new PropertiesAdapter(resource, element, (List<PropertyElement>) eobject.eGet(feature)); + } else { + ret = new ListAdapter(resource, element, (List<?>) eobject.eGet(feature), elementType); + } + } else if(feature instanceof EReference) { + EReference ref = (EReference) feature; + EObject eo = (EObject) eobject.eGet(feature); + if(null == eo) { + eo = PomFactory.eINSTANCE.create(ref.getEReferenceType()); + eobject.eSet(ref, eo); + } + + EClass elementType = ref.getEReferenceType(); + if(elementType != null && elementType.getClassifierID() == PomPackage.Literals.CONFIGURATION.getClassifierID()) { + ret = new ConfigurationAdapter(resource, element, (Configuration) eobject.eGet(feature)); } else { ret = new ModelObjectAdapter(this.resource, eo, element); ((ModelObjectAdapter) ret).eobject.eAdapters().add((ModelObjectAdapter) ret); } - } else { - ret = new ValueUpdateAdapter(resource, element, eobject, feature); - } - if (isNew) { - formatNode(element); - } - ((IDOMElement) element).addAdapter(ret); - childAdapters.put(feature, ret); - } - return ret; - } - - /** - * Removes the dom child matching the feature. - * - * @param feature - */ - private void removeDomChild(EStructuralFeature feature) { - TranslatorAdapter ta = childAdapters.get(feature); - if (ta != null && ta.getNode() != null) { - removeChildElement(ta.getNode()); - } - childAdapters.remove(feature); - } - - /** - * Inserts an element under the current node, attempting to preserve proper - * node ordering. - * - * @param element - * @param position - */ - private void insertElement(Element element) { - Node beforeNode = null; - boolean searching = false; - for (EStructuralFeature feature : eobject.eClass() - .getEStructuralFeatures()) { - if (element.getLocalName().equals(feature.getName())) { - searching = true; - } - if (searching) { - beforeNode = getFirstChildWithName(node, feature.getName()); - if (beforeNode != null) { - break; - } - } - } - - if (beforeNode == null) { - beforeNode = node.getLastChild(); - while (!(beforeNode == null - || beforeNode.getPreviousSibling() instanceof Element || beforeNode - .getPreviousSibling() == null)) { - beforeNode = beforeNode.getPreviousSibling(); - } - } - - if (beforeNode == null) { - node.appendChild(element); - } else { - node.insertBefore(element, beforeNode); - } - } - - /** - * Populates all child model objects from the child nodes in the dom tree. - */ - public void load() { - NodeList children = node.getChildNodes(); - int nChildren = children.getLength(); - for (int i = 0; i < nChildren; i++) { - Node child = children.item(i); - if (child instanceof Element) { - Element element = (Element) child; - EStructuralFeature feature = eobject.eClass() - .getEStructuralFeature(element.getLocalName()); - if (feature != null) { - createOrGetChildAdapter(feature).load(); - } - } - - } - } - - /** - * Populates all child dom objects from the model children. - */ - public void save() { - for (EStructuralFeature feature : eobject.eClass() - .getEStructuralFeatures()) { - if (eobject.eIsSet(feature)) { - Object o = eobject.eGet(feature); - if (!"".equals(o) && o != null) { //$NON-NLS-1$ - createOrGetChildAdapter(feature).save(); - } - } - } - } - - public Notifier getTarget() { - return target; - } - - public void setTarget(Notifier target) { - this.target = target; - } + } else { + ret = new ValueUpdateAdapter(resource, element, eobject, feature); + } + if(isNew) { + formatNode(element); + } + ((IDOMElement) element).addAdapter(ret); + childAdapters.put(feature, ret); + } + return ret; + } + + /** + * Removes the dom child matching the feature. + * + * @param feature + */ + private void removeDomChild(EStructuralFeature feature) { + TranslatorAdapter ta = childAdapters.get(feature); + if(ta != null && ta.getNode() != null) { + removeChildElement(ta.getNode()); + } + childAdapters.remove(feature); + } + + /** + * Inserts an element under the current node, attempting to preserve proper node ordering. + * + * @param element + * @param position + */ + private void insertElement(Element element) { + Node beforeNode = null; + boolean searching = false; + for(EStructuralFeature feature : eobject.eClass().getEStructuralFeatures()) { + if(element.getLocalName().equals(feature.getName())) { + searching = true; + } + if(searching) { + beforeNode = getFirstChildWithName(node, feature.getName()); + if(beforeNode != null) { + break; + } + } + } + + if(beforeNode == null) { + beforeNode = node.getLastChild(); + while(!(beforeNode == null || beforeNode.getPreviousSibling() instanceof Element || beforeNode + .getPreviousSibling() == null)) { + beforeNode = beforeNode.getPreviousSibling(); + } + } + + if(beforeNode == null) { + node.appendChild(element); + } else { + node.insertBefore(element, beforeNode); + } + } + + /** + * Populates all child model objects from the child nodes in the dom tree. + */ + public void load() { + NodeList children = node.getChildNodes(); + int nChildren = children.getLength(); + for(int i = 0; i < nChildren; i++ ) { + Node child = children.item(i); + if(child instanceof Element) { + Element element = (Element) child; + EStructuralFeature feature = eobject.eClass().getEStructuralFeature(element.getLocalName()); + if(feature != null) { + createOrGetChildAdapter(feature).load(); + } + } + + } + } + + /** + * Populates all child dom objects from the model children. + */ + public void save() { + for(EStructuralFeature feature : eobject.eClass().getEStructuralFeatures()) { + if(eobject.eIsSet(feature)) { + Object o = eobject.eGet(feature); + if(!"".equals(o) && o != null) { //$NON-NLS-1$ + createOrGetChildAdapter(feature).save(); + } + } + } + } + + public Notifier getTarget() { + return target; + } + + public void setTarget(Notifier target) { + this.target = target; + } } |