/* * $Id: CheckstyleFindingType.java 1173 2008-09-22 10:04:44Z amandel $ * * Copyright 2006, The jCoderZ.org Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the jCoderZ.org Project nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.jcoderz.phoenix.report; import java.io.Serializable; import java.util.Comparator; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.bind.JAXBException; import org.jcoderz.phoenix.report.GenericReportReader.SourceFile; import org.jcoderz.phoenix.report.ftf.jaxb.FindingDescription; import org.jcoderz.phoenix.report.jaxb.Item; import org.jcoderz.phoenix.report.jaxb.ObjectFactory; /** * Enumeration type for generic findings. * The description and patterns are read from a xml file. * * @author Andreas Mandel */ public final class GenericFindingType extends FindingType { private final Pattern mPattern; private final int mPriority; private final FindingDescription mFindingDescription; private final int mTextPos; private final int mLineStart; private final int mLineEnd; private final int mColumnStart; private final int mColumnEnd; private final int mSourceText; private final boolean mSourceColumnByCaret; private final Severity mSeverity; private final boolean mIsGlobal; private final ObjectFactory mOf = new ObjectFactory(); // private final Severity mSeverity; /** * Create new finding type based on xml description. * @param root the definition of the root finding description. * @param fd the definition of the detailed finding description. */ public GenericFindingType ( FindingDescription root, FindingDescription fd) { super(fd.getSymbol(), fd.getShortDescription(), fd.getDescription()); mPriority = fd.getPriority(); mPattern = Pattern.compile( fd.getPattern(), Pattern.MULTILINE + Pattern.UNIX_LINES); mFindingDescription = fd; mTextPos = fd.isSetTextPos() ? Integer.parseInt(fd.getTextPos()) : -1; mLineStart = fd.isSetLineStartPos() ? Integer.parseInt(fd.getLineStartPos()) : -1; mLineEnd = fd.isSetLineEndPos() ? Integer.parseInt(fd.getLineEndPos()) : -1; if (fd.isSetColumnStartPos() && "caret".equals(fd.getColumnStartPos())) { mColumnStart = -1; mSourceColumnByCaret = true; } else { mColumnStart = fd.isSetColumnStartPos() ? Integer.parseInt(fd.getColumnStartPos()) : -1; mSourceColumnByCaret = false; } mColumnEnd = fd.isSetColumnEndPos() ? Integer.parseInt(fd.getColumnEndPos()) : -1; mSourceText = fd.isSetSourceTextPos() ? Integer.parseInt(fd.getSourceTextPos()) : -1; mSeverity = fd.isSetSeverity() ? fd.getSeverity() : null; mIsGlobal = fd.isGlobal(); } /** * Try to match the given method and fill the item * accordingly if a match is found. * @param sf the input source read. Allows to set the new file position. * @param message the message to parse. * @return a new Item with available data filled or null. * @throws JAXBException if Item creation fails on jaxb level. */ public Item createItem (SourceFile sf, String message) throws JAXBException { Item result = null; final Matcher match = mPattern.matcher(message); if (match.lookingAt()) { sf.setPos(sf.getPos() + match.end() + 1); result = mOf.createItem(); result.setFindingType(getSymbol()); if (mTextPos != -1) { result.setMessage(match.group(mTextPos)); } else { result.setMessage(match.group()); } if (mLineStart != -1) { result.setLine(Integer.parseInt(match.group(mLineStart))); } if (mLineEnd != -1) { result.setEndLine(Integer.parseInt(match.group(mLineEnd))); } if (mColumnStart != -1) { result.setColumn(Integer.parseInt(match.group(mColumnStart))); } if (mColumnEnd != -1) { result.setEndColumn(Integer.parseInt(match.group(mColumnEnd))); } if (mSourceText != -1) { result.setSourceText(match.group(mSourceText)); } if (mSeverity != null) { result.setSeverity(mSeverity); } if (mFindingDescription.isGlobal()) { result.setGlobal(true); } } return result; } /** @return the severity assigned to findings of this type by default. */ public Severity getSeverity () { return mSeverity; } /** * The priority used to match for this finding in relation to * other findings of this type. * The higher the value the higher is the priority of this pattern. * A catch all pattern like "(.*)" should therefore get a low * number (eg. {@link Integer#MIN_VALUE}) as priority. * Default priority is 0. */ private int getPriority () { return mPriority; } /** * @return the sourceColumnByCaret */ public boolean isSourceColumnByCaret () { return mSourceColumnByCaret; } /** * @return the isGlobal */ public boolean isGlobal () { return mIsGlobal; } /** * Init of the enum. */ public static void initialize () { // already done } /** * Class to sort {@link GenericFindingType}s by their priority. */ public static class OrderByPriority implements Comparator<GenericFindingType>, Serializable { private static final long serialVersionUID = 1L; /** {@inheritDoc} */ public int compare (GenericFindingType o1, GenericFindingType o2) { final int result; if (o1.getPriority() > o2.getPriority()) { result = -1; } else if (o1.getPriority() < o2.getPriority()) { result = 1; } else { result = o1.getSymbol().compareTo(o2.getSymbol()); } return result; } } }