All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.databene.dbsanity.report.DefectsPageModule Maven / Gradle / Ivy

Go to download

DB Sanity is a tool for verifying a database's sanity and data integrity.

There is a newer version: 0.9.4
Show newest version
/*
 * (c) Copyright 2010-2011 by Volker Bergmann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, is permitted under the terms of the
 * GNU General Public License (GPL).
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
 * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
 * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 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.databene.dbsanity.report;

import java.io.File;

import org.databene.commons.Converter;
import org.databene.commons.FileUtil;
import org.databene.commons.converter.ConverterManager;
import org.databene.dbsanity.ExecutionMode;
import org.databene.dbsanity.html.HtmlPrintStream;
import org.databene.dbsanity.model.SanityCheck;
import org.databene.html.HTMLUtil;

/**
 * {@link ReportModule} implementation which creates an HTML page for each failed check.
 * The page lists the faulty data in a table.

* Created: 13.10.2010 18:50:32 * @since 1.0 * @author Volker Bergmann */ public class DefectsPageModule extends AbstractReportModule { private String latestFailedCheck; private int latestDefectCount; private HtmlPrintStream out; private char c = '/'; private Converter[] columnConverters; @Override public void failure(SanityCheck check, Object[] errorInfo, String[] infoHeaders) { if (!check.getName().equals(latestFailedCheck)) { if (latestFailedCheck != null) closeCurrentFile(); startNewFile(check, errorInfo, infoHeaders); this.latestDefectCount = 0; } if (context.getDefectRowLimit() <= 0 || latestDefectCount < context.getDefectRowLimit()) printFailureLine(errorInfo); this.latestFailedCheck = check.getName(); this.latestDefectCount++; } public void startNewFile(SanityCheck check, Object[] errorInfo, String[] infoHeaders) { try { String title = "Defect List of check '" + check.getName() + "'"; File file = check.getDefectsOrErrorPage(); FileUtil.ensureDirectoryExists(file.getParentFile()); out = openNewFile(file, title); context.printNavBar(file, out, ReportUtil.docRef(check)); renderCheckInfo(check, out); startDefectList(infoHeaders, errorInfo); } catch (Exception e) { throw new RuntimeException("Unexpected error", e); } } @SuppressWarnings("unchecked") public void startDefectList(String[] infoHeaders, Object[] errorInfo) { out.startModule("Defects"); out.startTable(); printFailureInfoHeader(infoHeaders); columnConverters = new Converter[errorInfo.length]; for (int i = 0; i < errorInfo.length; i++) if (errorInfo[i] != null) columnConverters[i] = (Converter) ConverterManager.getInstance().createConverter(errorInfo[i].getClass(), String.class); } @Override public void close() { closeCurrentFile(); } private char next(char c) { switch (c) { case '/' : return '-'; case '-' : return '\\'; case '\\' : return '|'; default : return '/'; } } protected void closeCurrentFile() { if (out != null) { if (latestFailedCheck != null) { out.endTable(); out.endModule(); } super.closeFile(out); out = null; } } private void printFailureInfoHeader(String[] errorInfo) { out.startTableRow(); for (String header : errorInfo) out.render(headerCell(header).withClass("td_defect")); out.endTableRow(); } private void printFailureLine(Object[] errorInfo) { out.startTableRow(); for (int i = 0; i < errorInfo.length; i++) out.render(cell(renderCellValue(errorInfo[i], i)).withClass("td_defect")); out.endTableRow(); // print activity indicator or defect data to console switch ((ExecutionMode) context.get("executionMode")) { case VERBOSE : printDefectDataToConsole(errorInfo); break; case DEFAULT : System.out.print((c = next(c)) + "\r"); break; } } @SuppressWarnings("unchecked") private String renderCellValue(Object value, int index) { if (value == null) return "[null]"; if (value instanceof CharSequence) { String rawString = HTMLUtil.escape((String) value); int firstWordChar = firstNonWhitespaceIndex(rawString); int lastWordChar = lastNonWhitespaceIndex(rawString); StringBuilder builder = new StringBuilder(); for (int i = 0; i < firstWordChar; i++) builder.append("♦"); builder.append(HTMLUtil.escape(rawString.substring(firstWordChar, lastWordChar + 1))); for (int i = lastWordChar; i < rawString.length() - 1; i++) builder.append("♦"); return builder.toString(); } else { if (columnConverters[index] == null) columnConverters[index] = (Converter) ConverterManager.getInstance().createConverter(value.getClass(), String.class); return columnConverters[index].convert(value); } } private int firstNonWhitespaceIndex(String text) { int i = 0; while (i < text.length() && Character.isWhitespace(text.charAt(i))) i++; return i; } private int lastNonWhitespaceIndex(String text) { int i = text.length() - 1; while (i > 0 && Character.isWhitespace(text.charAt(i))) i--; return i; } private void printDefectDataToConsole(Object[] errorInfo) { System.out.print("Defective record: " + errorInfo[0]); for (int i = 1; i < errorInfo.length; i++) System.out.print(" " + renderCellValue(errorInfo[i], i)); System.out.println(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy