001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2014 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * SonarQube is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * SonarQube is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public License
017     * along with this program; if not, write to the Free Software Foundation,
018     * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019     */
020    package org.sonar.batch.profiling;
021    
022    import org.sonar.api.utils.System2;
023    import org.sonar.batch.phases.Phases.Phase;
024    
025    import java.util.HashMap;
026    import java.util.Map;
027    import java.util.Map.Entry;
028    
029    public class PhaseProfiling extends AbstractTimeProfiling {
030    
031      private final Phase phase;
032    
033      private Map<String, ItemProfiling> profilingPerItem = new HashMap<String, ItemProfiling>();
034    
035      PhaseProfiling(System2 system, Phase phase) {
036        super(system);
037        this.phase = phase;
038      }
039    
040      public static PhaseProfiling create(System2 system, Phase phase) {
041        return new PhaseProfiling(system, phase);
042      }
043    
044      public Phase phase() {
045        return phase;
046      }
047    
048      public boolean hasItems() {
049        return !profilingPerItem.isEmpty();
050      }
051    
052      public ItemProfiling getProfilingPerItem(Object item) {
053        String stringOrSimpleName = toStringOrSimpleName(item);
054        return profilingPerItem.get(stringOrSimpleName);
055      }
056    
057      public void newItemProfiling(Object item) {
058        String stringOrSimpleName = toStringOrSimpleName(item);
059        profilingPerItem.put(stringOrSimpleName, new ItemProfiling(system(), stringOrSimpleName));
060      }
061    
062      public void newItemProfiling(String itemName) {
063        profilingPerItem.put(itemName, new ItemProfiling(system(), itemName));
064      }
065    
066      public void merge(PhaseProfiling other) {
067        super.add(other);
068        for (Entry<String, ItemProfiling> entry : other.profilingPerItem.entrySet()) {
069          if (!this.profilingPerItem.containsKey(entry.getKey())) {
070            newItemProfiling(entry.getKey());
071          }
072          this.getProfilingPerItem(entry.getKey()).add(entry.getValue());
073        }
074      }
075    
076      public void dump() {
077        double percent = this.totalTime() / 100.0;
078        for (ItemProfiling itemProfiling : truncate(sortByDescendingTotalTime(profilingPerItem).values())) {
079          println("   o " + itemProfiling.itemName() + ": ", percent, itemProfiling);
080        }
081      }
082    
083      /**
084       * Try to use toString if it is not the default {@link Object#toString()}. Else use {@link Class#getSimpleName()}
085       * @param o
086       * @return
087       */
088      private String toStringOrSimpleName(Object o) {
089        String toString = o.toString();
090        if (toString == null || toString.startsWith(o.getClass().getName())) {
091          return o.getClass().getSimpleName();
092        }
093        return toString;
094      }
095    
096    }