/*******************************************************************************
* 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.wst.sse.core.internal.format.IStructuredFormatProcessor;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.xml.core.internal.cleanup.CleanupProcessorXML;
import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
import org.springframework.ide.eclipse.beans.core.BeansCorePlugin;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansTypedString;
import org.springframework.ide.eclipse.beans.core.model.IBean;
import org.springframework.ide.eclipse.beans.core.model.IBeanProperty;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* This class converts legacy declarations of JndiObjectFactory to use the new
* namespace syntax. The input is an error marker identifying the instance of
* the legacy syntax to be converted. Note: This class is not currently in use
* because the UseNameSpaceSyntaxMarkerResolution has not been released.
* @author Wesley Coelho
* @author Leo Dos Santos
* @author Christian Dupuis
*/
public class JndiObjectFactorySyntaxConverter {
private static final String JEE_NAMESPACE_URL_ATTRIBUTE_NAME = "xmlns:jee";
private static final String JEE_NAMESPACE_URL = "http://www.springframework.org/schema/jee";
private static final String SCHEMA_LOCATION_ATTRIBUTE_NAME = "xsi:schemaLocation";
private static final String SCHEMA_LOCATION = "http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd";
private static final String NAMESPACE_JNDI_ELEMENT_NAME = "jee:jndi-lookup";
private static final String ID_ATTRIBUTE_NAME = "id";
public void convert(IMarker marker) throws CoreException {
IStructuredModel model = null;
try {
model = XmlQuickFixUtil.getModel(marker);
Element legacyXmlElement = XmlQuickFixUtil.getMarkerElement(model, marker);
insertNamespaceDeclaration(model);
IBean jndiObjectFactoryBean = (IBean) BeansCorePlugin.getModel().getElement(
marker.getAttribute("elementId", ""));
Element namespaceJndiElement = createNamespaceSyntaxXmlElement(jndiObjectFactoryBean,
NAMESPACE_JNDI_ELEMENT_NAME, legacyXmlElement.getOwnerDocument());
// Add the new element node
legacyXmlElement.getParentNode().insertBefore(namespaceJndiElement, legacyXmlElement);
// Format the new element node
IStructuredFormatProcessor formatProcessor = new FormatProcessorXML();
CleanupProcessorXML cleanupProcessor = new CleanupProcessorXML();
cleanupProcessor.getCleanupPreferences().setCompressEmptyElementTags(true);
formatProcessor.formatNode(namespaceJndiElement);
cleanupProcessor.cleanupNode(namespaceJndiElement);
legacyXmlElement.getParentNode().removeChild(legacyXmlElement);
}
finally {
if (model != null) {
model.releaseFromEdit();
}
}
}
private Element createNamespaceSyntaxXmlElement(IBean bean, String elementName, Document document) {
Element jndiObjectFactoryElement = document.createElement(elementName);
jndiObjectFactoryElement.setAttribute(ID_ATTRIBUTE_NAME, bean.getElementName());
// Iterate over the properties and represent them as namespace-syntax
// attributes
for (IBeanProperty currProperty : bean.getProperties()) {
Object value = currProperty.getValue();
if (value instanceof BeansTypedString) {
BeansTypedString propertyValue = (BeansTypedString) value;
String propertyName = currProperty.getElementName();
jndiObjectFactoryElement.setAttribute(toHyphenFormat(propertyName), propertyValue.getString());
}
}
return jndiObjectFactoryElement;
}
private Node insertNamespaceDeclaration(IStructuredModel model) {
IStructuredDocumentRegion beansRegion = model.getStructuredDocument().getFirstStructuredDocumentRegion()
.getNext().getNext();
Element beansElement = (Element) model.getIndexedRegion(beansRegion.getStartOffset());
beansElement.setAttribute(JEE_NAMESPACE_URL_ATTRIBUTE_NAME, JEE_NAMESPACE_URL);
String schemaLocation = beansElement.getAttribute(SCHEMA_LOCATION_ATTRIBUTE_NAME);
if (schemaLocation != null) {
if (schemaLocation.indexOf(SCHEMA_LOCATION) == -1) {
schemaLocation += " \n\t\t" + SCHEMA_LOCATION;
beansElement.setAttribute(SCHEMA_LOCATION_ATTRIBUTE_NAME, schemaLocation);
}
}
else {
beansElement.setAttribute(SCHEMA_LOCATION_ATTRIBUTE_NAME, SCHEMA_LOCATION);
}
return beansElement;
}
/**
* Converts the given string according to the convention: camelCase ->
* camel-case
*/
private String toHyphenFormat(String camelFormat) {
String hyphenFormat = camelFormat.replaceAll("[A-Z]", "-$0");
hyphenFormat = hyphenFormat.toLowerCase();
return hyphenFormat;
}
}