001package org.nasdanika.html.model.app.gen.maven; 002 003import java.io.PrintStream; 004import java.util.Arrays; 005import java.util.concurrent.CancellationException; 006 007import org.apache.maven.plugin.logging.Log; 008import org.nasdanika.common.ProgressMonitor; 009import org.nasdanika.common.Status; 010 011/** 012 * Progress monitor reporting to a {@link PrintStream}, e.g. ``System.out``. 013 * This monitor indents sub-tasks and worked messages. It can be thought of as a hierarchical logger. 014 * @author Pavel 015 * 016 */ 017public class LogProgressMonitor implements ProgressMonitor { 018 019 private Log log; 020 private String indent; 021 protected int indentIncrement = 2; 022 private boolean cancelled; 023 024 /** 025 * Constructs a progress monitor for a given log. 026 */ 027 public LogProgressMonitor(Log log, int indent, int indentIncrement) { 028 this.log = log; 029 StringBuilder indentBuilder = new StringBuilder(); 030 for (int i = 0; i < indent; ++i) { 031 indentBuilder.append(' '); 032 } 033 this.indent = indentBuilder.toString(); 034 } 035 036 @Override 037 public boolean isCancelled() { 038 return cancelled; 039 } 040 041 @Override 042 public ProgressMonitor split(String taskName, double size, Object... data) { 043 if (isCancelled()) { 044 throw new CancellationException(); 045 } 046 log.info(indent + " " + taskName + " ("+size+")"); 047 if (data != null) { 048 for (Object d: data) { 049 log.info(formatDetail(d, indent + " ")); 050 } 051 } 052 return new LogProgressMonitor(log, indent.length() + indentIncrement, indentIncrement) { 053 054 @Override 055 public boolean isCancelled() { 056 return LogProgressMonitor.this.isCancelled(); 057 } 058 059 }; 060 } 061 062 /** 063 * Formats detail element for output. This implementation concatenates the indent with the detail. 064 * @param detail 065 * @param indent 066 * @return 067 */ 068 protected String formatDetail(Object detail, String indent) { 069 return indent + detail; 070 } 071 072 @Override 073 public void worked(Status status, double work, String progressMessage, Object... data) { 074 switch (status) { 075 case ERROR: 076 case FAIL: 077 log.error(indent + " [" + status + " " + work + "] " + progressMessage); 078 if (data.length > 0) { 079 log.error(": " + Arrays.deepToString(data)); 080 } 081 break; 082 case WARNING: 083 log.warn(indent + " [" + status + " " + work + "] " + progressMessage); 084 if (data.length > 0) { 085 log.warn(": " + Arrays.deepToString(data)); 086 } 087 break; 088 case CANCEL: 089 case INFO: 090 case SUCCESS: 091 default: 092 log.info(indent + " [" + status + " " + work + "] " + progressMessage); 093 if (data.length > 0) { 094 log.info(": " + Arrays.deepToString(data)); 095 } 096 if (status == Status.CANCEL) { 097 cancelled = true; 098 } 099 } 100 } 101 102 @Override 103 public ProgressMonitor setWorkRemaining(double size) { 104 // NOP 105 return this; 106 } 107 108 @Override 109 public void close() { 110 // NOP 111 } 112 113}