/****************************************************************************** * Copyright (c) 2009-2013, Linagora * * 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: * Linagora - initial API and implementation *******************************************************************************/ package com.ebmwebsourcing.petals.common.internal.provisional.utils; import java.util.List; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.w3c.dom.Node; import com.ebmwebsourcing.petals.common.internal.PetalsCommonPlugin; /** * @author Vincent Zurczak - EBM WebSourcing */ public final class MarkerUtils { /** * Private constructor for utility class. */ private MarkerUtils() { // nothing } /** * Gets the {@link IMessageProvider} constant from an {@link IMarker} severity constant. * @param markerSeverity * @return */ public static int getMessageSeverityFromMarkerSeverity( int markerSeverity ) { int type; switch( markerSeverity ) { case IMarker.SEVERITY_ERROR: type = IMessageProvider.ERROR; break; case IMarker.SEVERITY_WARNING: type = IMessageProvider.WARNING; break; case IMarker.SEVERITY_INFO: type = IMessageProvider.INFORMATION; break; default: type = IMessageProvider.NONE; } return type; } /** * Gets the maximum severity. * @param markers a list of markers (not null) * @return the maximum severity * @see IStatus */ public static int getMaximumSeverity( List<IMarker> markers ) { int result = IStatus.OK; loop: for( IMarker marker : markers ) { int severity = marker.getAttribute( IMarker.SEVERITY, IStatus.OK ); switch( severity ) { case IMarker.SEVERITY_ERROR: result = IStatus.ERROR; break loop; case IMarker.SEVERITY_WARNING: result = IStatus.WARNING; break; case IMarker.SEVERITY_INFO: if( result == IStatus.OK ) result = IStatus.INFO; break; } } return result; } /** * Not sensitive to name spaces (for instance, but not sure either it will be one day). */ private static final XPath X_PATH = XPathFactory.newInstance().newXPath(); /** * Resolves the line numbers on marked files. * @param file the marked file * @param loadModel true to load the model if it was not loaded, false to only use an existing instance * @param markerId the ID of the markers to find * @param markerAttribute the attribute whose value is an XPath expression. * <p> * The XPath expression is applied on the file's in-memory document.<br /> * If the document was not already loaded (e.g. by an editor), then nothing is resolved.<br /> * If an element is found, then its line number is resolved using WTP's XML API. * The found line number is then written on the file marker. * </p> */ @SuppressWarnings( "restriction" ) public static void resolveLineNumbers( IFile file, boolean loadModel, String markerId, String markerAttribute ) { IStructuredModel model = null; try { int line = 0; model = StructuredModelManager.getModelManager().getExistingModelForRead( file ); try { if( model == null && loadModel ) model = StructuredModelManager.getModelManager().getModelForRead( file ); } catch( Exception e2 ) { // nothing } if( model != null && file.exists() && markerAttribute != null && markerAttribute.trim().length() != 0 ) { // Get the markers from the file IMarker[] markers; try { markers = file.findMarkers( markerId, true, IResource.DEPTH_ZERO ); } catch( CoreException e1 ) { PetalsCommonPlugin.log( e1, IStatus.WARNING ); markers = new IMarker[ 0 ]; } if( markers == null ) markers = new IMarker[ 0 ]; for( IMarker marker : markers ) { // Get the XPath expression from the right attribute String xpathLocation = marker.getAttribute( markerAttribute, null ); if( StringUtils.isEmpty( xpathLocation )) continue; // Resolve the XML element and get its line number Node node = null; try { node = (Node) X_PATH.evaluate( xpathLocation, ((IDOMModel) model).getDocument(), XPathConstants.NODE ); } catch( XPathExpressionException e ) { PetalsCommonPlugin.log( e, IStatus.WARNING, "Failed to find the element " + xpathLocation + "." ); } if( node != null ) { int offset = -1; if( node instanceof IDOMElement ) offset = ((IDOMElement) node).getStartOffset(); else if( node instanceof IDOMAttr ) offset = ((IDOMAttr) node).getStartOffset(); line = model.getStructuredDocument().getLineOfOffset( offset ) + 1; } // Debug else { System.out.println( "=> '" + xpathLocation + "' could not be resolved." ); } // Update the line attribute on the marker try { marker.setAttribute( IMarker.LINE_NUMBER, line ); } catch( CoreException e ) { PetalsCommonPlugin.log( e, IStatus.ERROR ); } } } } finally { if( model != null ) model.releaseFromRead(); } } }