/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.pig.impl.plan ; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ArrayList ; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.pig.PigWarning; /*** * This class is used for collecting all messages (error + warning) in * compilation process. These messages are reported back to users * at the end of compilation. * * iterator() has to be called after CompilationMessageCollector is fully * populated otherwise the state is undefined. */ public class CompilationMessageCollector implements Iterable<CompilationMessageCollector.Message> { public enum MessageType { Unknown, Error, Warning, Info } public static class Message { private String msg = null ; private MessageType msgType = MessageType.Unknown ; private Enum kind = null; public Message(String message, MessageType messageType) { msg = message ; msgType = messageType ; } public Message(String message, MessageType messageType, Enum kind) { this(message, messageType); this.kind = kind; } public String getMessage() { return msg ; } public MessageType getMessageType() { return msgType ; } public Enum getKind() { return kind; } } private List<Message> messageList = new ArrayList<Message>() ; public CompilationMessageCollector() { // nothing here } public void collect(String message, MessageType messageType) { messageList.add(new Message(message, messageType)) ; } public void collect(String message, MessageType messageType, Enum kind) { messageList.add(new Message(message, messageType, kind)) ; } protected boolean hasMessageType(MessageType messageType) { Iterator<Message> iter = iterator() ; while(iter.hasNext()) { if (iter.next().getMessageType() == messageType) { return true ; } } return false ; } public boolean hasError() { return hasMessageType(MessageType.Error); } public Iterator<Message> iterator() { return messageList.iterator() ; } public boolean hasMessage() { return messageList.size() > 0 ; } public int size() { return messageList.size() ; } public Message get(int i) { return messageList.get(i) ; } public Map<Enum, Long> getKindAggregate(MessageType messageType) { Map<Enum, Long> aggMap = new HashMap<Enum, Long>(); Iterator<Message> iter = iterator() ; while(iter.hasNext()) { Message message = iter.next(); if (message.getMessageType() == messageType) { Enum kind = message.getKind(); if(kind != null) { Long count = aggMap.get(kind); count = (count == null? 1 : ++count); aggMap.put(kind, count); } } } return aggMap; } public static void logAggregate(Map<Enum, Long> aggMap, MessageType messageType, Log log) { long nullCounterCount = aggMap.get(PigWarning.NULL_COUNTER_COUNT)==null?0 : aggMap.get(PigWarning.NULL_COUNTER_COUNT); if (nullCounterCount!=0 && aggMap.size()>1) // PigWarning.NULL_COUNTER_COUNT is definitely in appMap logMessage("Unable to retrieve hadoop counter for " + nullCounterCount + " jobs, the number following warnings may not be correct", messageType, log); for(Map.Entry<Enum, Long> e: aggMap.entrySet()) { if (e.getKey() !=PigWarning.NULL_COUNTER_COUNT) { Long count = e.getValue(); if(count != null && count > 0) { String message = "Encountered " + messageType + " " + e.getKey().toString() + " " + count + " time(s)."; logMessage(message, messageType, log); } } } } public static void logMessages(CompilationMessageCollector messageCollector, MessageType messageType, boolean aggregate, Log log) { if(aggregate) { Map<Enum, Long> aggMap = messageCollector.getKindAggregate(messageType); logAggregate(aggMap, messageType, log); } else { Iterator<Message> messageIter = messageCollector.iterator(); while(messageIter.hasNext()) { Message message = messageIter.next(); if(message.getMessageType() == messageType) { logMessage(message.getMessage(), messageType, log); } } } } public void logMessages(MessageType messageType, boolean aggregate, Log log) { logMessages(this, messageType, aggregate, log); } public static void logAllMessages(CompilationMessageCollector messageCollector, Log log) { Iterator<Message> messageIter = messageCollector.iterator(); while(messageIter.hasNext()) { Message message = messageIter.next(); logMessage(message.getMessage(), message.getMessageType(), log); } } public void logAllMessages(Log log) { logAllMessages(this, log); } private static void logMessage(String messageString, MessageType messageType, Log log) { switch(messageType) { case Info: log.info(messageString); break; case Warning: log.warn(messageString); break; case Error: log.error(messageString); } } }