com.ebmwebsourcing.petals.common.internal.provisional.utils.MarkerUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.ebmwebsourcing.petals.common.internal.provisional.utils.MarkerUtils.java

Source

/******************************************************************************
 * 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();
        }
    }
}