/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * 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: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.internal.bestpractices.quickfix; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IMarkerResolution2; import org.eclipse.ui.part.MultiPageEditorPart; import org.eclipse.wst.sse.core.internal.format.IStructuredFormatProcessor; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.sse.ui.StructuredTextEditor; import org.eclipse.wst.xml.core.internal.document.ElementImpl; import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML; import org.springsource.ide.eclipse.commons.core.StatusHandler; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; /** * Resolution for referenced bean not found markers. Creates a corresponding * bean definition below the bean with the marker. * @author Wesley Coelho * @author Leo Dos Santos * @author Christian Dupuis * @author Terry Denney */ public class CreateReferencedBeanDefinitionMarkerResolution implements IMarkerResolution2 { private static final String MESSAGE_ATTRIBUTE_KEY = "message"; private String missingBeanId = ""; public CreateReferencedBeanDefinitionMarkerResolution(IMarker marker) { String markerMessage = marker.getAttribute(MESSAGE_ATTRIBUTE_KEY, ""); missingBeanId = extractBeanId(markerMessage); } private String extractBeanId(String message) { final String startTag = "bean '"; int startPos = message.indexOf(startTag) + startTag.length(); int endPos = message.indexOf("'", startPos); return message.substring(startPos, endPos); } public String getDescription() { return "Create bean definition with id " + missingBeanId; } public Image getImage() { return null; } public String getLabel() { return "Create bean definition with id " + missingBeanId; } public void run(IMarker marker) { IStructuredModel model = null; Element beanElement = null; try { model = XmlQuickFixUtil.getModel(marker); beanElement = XmlQuickFixUtil.getMarkerElement(model, marker); if (model != null) { if (beanElement != null) { Document document = beanElement.getOwnerDocument(); Element newBeanElement = document.createElement("bean"); beanElement.getParentNode().insertBefore(newBeanElement, beanElement.getNextSibling()); newBeanElement.setAttribute("id", missingBeanId); newBeanElement.setAttribute("class", ""); Text spacerNode = document.createTextNode("\n\n"); beanElement.getParentNode().insertBefore(spacerNode, newBeanElement); IStructuredFormatProcessor formatProcessor = new FormatProcessorXML(); formatProcessor.formatNode(newBeanElement); XmlQuickFixUtil.saveMarkedFile(marker); IEditorPart editor = XmlQuickFixUtil.getMarkedEditor(marker); setCursorPositionToClassAttribute((MultiPageEditorPart) editor, (ElementImpl) newBeanElement); } } } catch (CoreException e) { StatusHandler.log(e.getStatus()); } finally { if (model != null) { model.releaseFromEdit(); } } } /** * Attempts to set the cursor position to the class attribute value of the * given XML Element that corresponds to a bean definition. Preconditions: */ private void setCursorPositionToClassAttribute(MultiPageEditorPart xmlEditor, ElementImpl newBeanElement) { IEditorPart[] editorParts = xmlEditor.findEditors(xmlEditor.getEditorInput()); for (IEditorPart currEditorPart : editorParts) { if (currEditorPart instanceof StructuredTextEditor) { StructuredTextEditor structuredTextEditor = (StructuredTextEditor) currEditorPart; int beanElementStartOffset = newBeanElement.getStartOffset(); String newBeanTextContent = newBeanElement.getFirstStructuredDocumentRegion().getFullText(); String classAttributeStartString = "class=\""; int classAttributeStartIndex = newBeanTextContent.indexOf(classAttributeStartString) + classAttributeStartString.length(); if (classAttributeStartIndex > 0) { int documentOffset = beanElementStartOffset + classAttributeStartIndex; structuredTextEditor.selectAndReveal(documentOffset, 0); currEditorPart.setFocus(); } } } } }