You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by st...@apache.org on 2011/08/16 23:18:21 UTC

svn commit: r1158449 - in /cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling: aspects/InvocationDispatcher.java component/ProfilingPngSerializer.java spring/AutomaticProfilerInstaller.java

Author: stevendolg
Date: Tue Aug 16 21:18:20 2011
New Revision: 1158449

URL: http://svn.apache.org/viewvc?rev=1158449&view=rev
Log:
reworked classes to fix warnings

Modified:
    cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/aspects/InvocationDispatcher.java
    cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/component/ProfilingPngSerializer.java
    cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/spring/AutomaticProfilerInstaller.java

Modified: cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/aspects/InvocationDispatcher.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/aspects/InvocationDispatcher.java?rev=1158449&r1=1158448&r2=1158449&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/aspects/InvocationDispatcher.java (original)
+++ cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/aspects/InvocationDispatcher.java Tue Aug 16 21:18:20 2011
@@ -19,6 +19,7 @@ package org.apache.cocoon.profiling.aspe
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.cocoon.pipeline.ProcessingException;
 import org.apache.cocoon.profiling.data.ProfilingData;
 import org.apache.cocoon.profiling.profiler.Profiler;
 import org.apache.cocoon.profiling.spring.AutomaticProfilerInstaller;
@@ -35,7 +36,6 @@ import org.slf4j.LoggerFactory;
  * <p>
  * New profilers can be installed with installProfiler(Profiler). More specific profilers will be
  * chosen first automatically. The recommended way to install a Profiler is to declare it as a
- * 
  * spring-managed bean. The {@link AutomaticProfilerInstaller} will install the Profiler
  * automatically on the correct InvocationDispatcher.
  * </p>
@@ -59,11 +59,10 @@ public class InvocationDispatcher {
      */
     public Object dispatch(ProceedingJoinPoint pjp) throws Throwable {
         Object target = pjp.getTarget();
-        ProfilingData data = new ProfilingData();
-
         Profiler<?> profiler = this.getProfiler(target);
-        String method = pjp.getSignature().getName();
 
+        String method = pjp.getSignature().getName();
+        ProfilingData data = new ProfilingData();
         try {
             profiler.before(data, target, method, pjp.getArgs());
             Object returnValue = pjp.proceed(pjp.getArgs());
@@ -81,21 +80,24 @@ public class InvocationDispatcher {
      * @param profiler the profiler to install
      */
     public void installProfiler(Profiler<?> profiler) {
-        Class<?> class1 = profiler.getTargetClass();
+        Class<?> targetClass = profiler.getTargetClass();
 
         // insertion position determined by type hierarchy
         for (int i = 0; i < this.profilers.size(); i++) {
-            Class<?> class2 = this.profilers.get(i).getTargetClass();
+            Class<?> installedTargetClass = this.profilers.get(i).getTargetClass();
+
+            if (!installedTargetClass.isAssignableFrom(targetClass)) {
+                continue;
+            }
 
-            if (class2.isAssignableFrom(class1)) {
-                if (class1.equals(class2)) {
-                    throw new RuntimeException(String.format("You are trying to install a profiler for '%s' "
-                            + "but for this class there is already a profiler registered: '%s'", class1.getName(),
-                            this.profilers.get(i).getClass().getName()));
-                }
-                this.profilers.add(i, profiler);
-                return;
+            if (targetClass.equals(installedTargetClass)) {
+                throw new IllegalArgumentException(String.format("You are trying to install a profiler for '%s' "
+                        + "but for this class there is already a profiler registered: '%s'", targetClass.getName(),
+                        this.profilers.get(i).getClass().getName()));
             }
+
+            this.profilers.add(i, profiler);
+            return;
         }
 
         this.profilers.add(profiler);
@@ -107,6 +109,7 @@ public class InvocationDispatcher {
                 return profiler;
             }
         }
-        throw new RuntimeException("No profiler found for " + target.getClass() + ".");
+
+        throw new ProcessingException("No profiler found for '" + target.getClass().getName() + "'.");
     }
 }

Modified: cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/component/ProfilingPngSerializer.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/component/ProfilingPngSerializer.java?rev=1158449&r1=1158448&r2=1158449&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/component/ProfilingPngSerializer.java (original)
+++ cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/component/ProfilingPngSerializer.java Tue Aug 16 21:18:20 2011
@@ -20,7 +20,6 @@ package org.apache.cocoon.profiling.comp
 
 import java.awt.Color;
 import java.awt.FontMetrics;
-import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.RenderingHints;
 import java.awt.image.BufferedImage;
@@ -35,7 +34,9 @@ import java.util.Map;
 
 import javax.imageio.ImageIO;
 
+import org.apache.cocoon.pipeline.ProcessingException;
 import org.apache.cocoon.pipeline.caching.CacheKey;
+import org.apache.cocoon.pipeline.caching.CompoundCacheKey;
 import org.apache.cocoon.pipeline.caching.ParameterCacheKey;
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
 import org.apache.cocoon.pipeline.component.Finisher;
@@ -58,6 +59,8 @@ public class ProfilingPngSerializer impl
 
     private OutputStream outputStream;
 
+    private int imageWidth;
+
     /**
      * {@inheritDoc}
      */
@@ -73,7 +76,7 @@ public class ProfilingPngSerializer impl
     }
 
     /**
-     * Writes the image data to the output stream.
+     * {@inheritDoc}
      */
     public void finish() {
     	// nothing to do
@@ -92,10 +95,11 @@ public class ProfilingPngSerializer impl
      */
     public void execute() {
         if (this.profilingData == null) {
-            new ErrorMessageDrawer().writeImage(this.outputStream);
-        } else {
-            new ProfilingDrawer(this.profilingData).writeImage(this.outputStream);
+            new ErrorMessageDrawer().writeImage(this.id, this.outputStream);
+            return;
         }
+
+        new ProfilingDrawer(this.profilingData, this.imageWidth).writeImage(this.outputStream);
     }
 
     public void setProfilingDataHolder(ProfilingDataHolder dataHolder) {
@@ -106,267 +110,299 @@ public class ProfilingPngSerializer impl
      * {@inheritDoc}
      */
     public void setup(Map<String, Object> parameters) {
-    	// nothing to do
+        String widthParameter = (String) parameters.get("width");
+        if (widthParameter != null) {
+            this.imageWidth = Integer.parseInt(widthParameter);
+        } else {
+            this.imageWidth = 1000;
+        }
     }
 
-    private class ProfilingDrawer {
+    private static class ProfilingDrawer {
 
-        private static final int BAR_WIDTH = 520;
+        private static final ProfilingDataComparator PROFILING_DATA_COMPARATOR = new ProfilingDataComparator();
 
+        private static final Color INACTIVE_BAR_COLOR = Color.ORANGE.brighter();
+        private static final Color ACTIVE_BAR_COLOR = Color.GREEN.darker();
+        private static final Color BAR_BACKGROUND_COLOR = new Color(235, 235, 235);
+
+        private static final int MAX_DISPLAY_NAME_WIDTH = 350;
+        private static final int MAX_EXECUTION_TIME_WIDTH = 80;
+        private static final int MARGIN = 10;
+
+        private static final int X_OFFSET = 0;
+        private static final int Y_OFFSET = 10;
+        private static final int LINE_HEIGHT = 20;
+        private static final int BAR_HEIGHT = 15;
+        
         private Map<String, Integer> lineNumberMap = new HashMap<String, Integer>();
-
         private List<List<ProfilingData>> lineNumber2profilingData = new ArrayList<List<ProfilingData>>();
 
-        private long startTime;
-        private long endTime;
-
-        private final int LINE_HEIGHT = 20;
-        private final int Y_OFFSET = 10;
-        private final int X_OFFSET = 0;
-        private final int MAX_STRING_WIDTH = 350;
-
-        private int maxStringWidth = 0;
-
-        private ProfilingData profilingData;
-
-        public ProfilingDrawer(ProfilingData profilingData) {
-            this.profilingData = profilingData;
-
-            List<ProfilingData> data = this.transformTreeToList();
-
-            this.startTime = data.get(0).getInvocationStartTime();
-            this.endTime = data.get(0).getInvocationEndTime();
-
-            for (ProfilingData pd : data) {
-                if (this.getLineNumber(pd) == null) {
-                    this.lineNumberMap.put(pd.getId(), this.lineNumberMap.size());
+        private final long startTime;
+        private final long endTime;
+        private final int imageWidth;
+
+        public ProfilingDrawer(ProfilingData profilingData, int imageWidth) {
+            this.imageWidth = imageWidth;
+
+            List<ProfilingData> profilingDataList = this.transformTreeToList(profilingData);
+            this.startTime = profilingDataList.get(0).getInvocationStartTime();
+            this.endTime = profilingDataList.get(0).getInvocationEndTime();
+
+            for (ProfilingData eachProfilingData : profilingDataList) {
+                if (this.getLineNumber(eachProfilingData) == null) {
+                    this.lineNumberMap.put(eachProfilingData.getId(), this.lineNumberMap.size());
                 }
             }
 
-            for (ProfilingData pd : data) {
-                Integer lineNumber = this.getLineNumber(pd);
-
-                List<ProfilingData> pds;
+            for (ProfilingData eachProfilingData : profilingDataList) {
+                int lineNumber = this.getLineNumber(eachProfilingData).intValue();
 
                 if (this.lineNumber2profilingData.size() <= lineNumber) {
-                    pds = new ArrayList<ProfilingData>();
-                    pds.add(pd);
+                    List<ProfilingData> pds = new ArrayList<ProfilingData>();
+                    pds.add(eachProfilingData);
                     this.lineNumber2profilingData.add(pds);
                 } else {
-                    this.lineNumber2profilingData.get(lineNumber).add(pd);
+                    this.lineNumber2profilingData.get(lineNumber).add(eachProfilingData);
                 }
             }
         }
 
-        private List<ProfilingData> transformTreeToList() {
-            ArrayList<ProfilingData> list = new ArrayList<ProfilingData>();
-            this.traverse(this.profilingData, list);
-            Collections.sort(list, new ProfilingDataComparator());
+        private List<ProfilingData> transformTreeToList(ProfilingData profilingData) {
+            List<ProfilingData> profilingDataList = new ArrayList<ProfilingData>();
+            this.traverse(profilingData, profilingDataList);
+
+            Collections.sort(profilingDataList, PROFILING_DATA_COMPARATOR);
 
-            return list;
+            return profilingDataList;
         }
 
-        private void traverse(ProfilingData profilingData2, ArrayList<ProfilingData> list) {
-            list.add(profilingData2);
+        private void traverse(ProfilingData profilingData, List<ProfilingData> profilingDataList) {
+            profilingDataList.add(profilingData);
 
-            for (ProfilingData pd : profilingData2.getChildren()) {
-                this.traverse(pd, list);
+            for (ProfilingData child : profilingData.getChildren()) {
+                this.traverse(child, profilingDataList);
             }
         }
 
-        private float factor(long x) {
+        private float factor(long time) {
             long executionTime = this.endTime - this.startTime;
-            long t = x - this.startTime;
+            long elapsedTime = time - this.startTime;
 
-            return t / (float) executionTime;
+            return elapsedTime / (float) executionTime;
         }
 
-        private Integer getLineNumber(ProfilingData pd) {
-            return this.lineNumberMap.get(pd.getId());
+        private Integer getLineNumber(ProfilingData profilingData) {
+            return this.lineNumberMap.get(profilingData.getId());
         }
 
-        private int getY(ProfilingData pd) {
-            return this.getLineNumber(pd) * this.LINE_HEIGHT + this.Y_OFFSET;
+        private int getY(ProfilingData profilingData) {
+            return this.getLineNumber(profilingData).intValue() * LINE_HEIGHT + Y_OFFSET;
         }
 
-        public void writeImage(OutputStream os) {
-            int height = this.X_OFFSET + this.lineNumber2profilingData.size() * this.LINE_HEIGHT;
-
-            BufferedImage bufferedImage = new BufferedImage(1000, height, BufferedImage.TYPE_INT_ARGB);
-            Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
-            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-            g.setBackground(Color.WHITE);
+        public void writeImage(OutputStream outputStream) {
+            int height = Y_OFFSET + this.lineNumber2profilingData.size() * LINE_HEIGHT;
 
-            FontMetrics metrics = g.getFontMetrics();
+            BufferedImage bufferedImage = new BufferedImage(this.imageWidth, height, BufferedImage.TYPE_INT_ARGB);
+            Graphics2D graphics2D = bufferedImage.createGraphics();
+            graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+            graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            graphics2D.setBackground(Color.WHITE);
 
-            this.drawDisplayNameStrings(g, metrics);
+            this.drawNamesAndTimes(graphics2D);
 
-            final int xOffset = this.X_OFFSET + this.maxStringWidth + 10;
-            final int yOffset = -10;
+            int yOffset = -10;
+            int xOffset = X_OFFSET + MAX_DISPLAY_NAME_WIDTH + MARGIN + MAX_EXECUTION_TIME_WIDTH + MARGIN;
+            int availableWidth = this.imageWidth - xOffset;
 
-            this.drawExecutionTimeStrings(g, xOffset);
+            this.drawGrayBars(graphics2D, xOffset, yOffset, availableWidth);
+            this.drawGreenBars(graphics2D, xOffset, yOffset, availableWidth);
+            this.drawOrangeBars(graphics2D, xOffset, yOffset, availableWidth);
+            this.drawCallerLines(graphics2D, xOffset, yOffset, availableWidth);
 
-            this.drawGrayBars(g, xOffset, yOffset);
-            this.drawGreenBars(g, xOffset, yOffset);
-            this.drawOrangeBars(g, xOffset, yOffset);
-            this.drawCallerLines(g, xOffset, yOffset);
-
-            g.dispose();
+            graphics2D.dispose();
 
             try {
-                ImageIO.write(bufferedImage, "png", os);
+                ImageIO.write(bufferedImage, "png", outputStream);
             } catch (IOException e) {
-                throw new RuntimeException(e);
+                throw new ProcessingException("Failed to render profiling image", e);
             }
         }
 
-        private void drawDisplayNameStrings(Graphics2D g, FontMetrics metrics) {
-            g.setColor(Color.BLACK);
-            for (List<ProfilingData> pds : this.lineNumber2profilingData) {
-                String displayName = pds.get(0).getDisplayName();
-                for (ProfilingData pd : pds) {
-                    if (pd.isDisplayNameSet()) {
-                        displayName = pd.getDisplayName();
-                        break;
-                    }
-                }
+        private void drawNamesAndTimes(Graphics2D graphics2D) {
+            graphics2D.setColor(Color.BLACK);
 
+            FontMetrics metrics = graphics2D.getFontMetrics();
+
+            for (List<ProfilingData> profilingDataList : this.lineNumber2profilingData) {
+                String displayName = this.getDisplayName(profilingDataList);
                 displayName = this.adaptToMaxWidth(metrics, displayName);
-                int stringWidth = metrics.stringWidth(displayName);
+                graphics2D.drawString(displayName, X_OFFSET, this.getY(profilingDataList.get(0)));
+
+                double executionTime = this.getExecutionTime(profilingDataList);
+                String formattedExecutionTime = String.format(Locale.US, "%.3fms", executionTime);
 
-                g.drawString(displayName, this.X_OFFSET, this.getY(pds.get(0)));
+                int stringWidth = metrics.stringWidth(formattedExecutionTime);
+                graphics2D.drawString(formattedExecutionTime, X_OFFSET + MAX_DISPLAY_NAME_WIDTH + MARGIN
+                        + MAX_EXECUTION_TIME_WIDTH - stringWidth,
+                        this.getY(profilingDataList.get(0)));
+            }
+        }
 
-                this.maxStringWidth = Math.max(this.maxStringWidth, stringWidth);
+        private String getDisplayName(List<ProfilingData> profilingDataList) {
+            for (ProfilingData eachProfilingData : profilingDataList) {
+                if (eachProfilingData.isDisplayNameSet()) {
+                    return eachProfilingData.getDisplayName();
+                }
             }
+
+            return profilingDataList.get(0).getDisplayName();
         }
 
-        private void drawGrayBars(Graphics2D g, final int xOffset, final int yOffset) {
-            g.setColor(new Color(235, 235, 235));
-            for (List<ProfilingData> pds : this.lineNumber2profilingData) {
-                g.fillRect(xOffset, this.getY(pds.get(0)) + yOffset, BAR_WIDTH, 15);
+        private void drawGrayBars(Graphics2D graphics2D, final int xOffset, final int yOffset, int availableWidth) {
+            graphics2D.setColor(BAR_BACKGROUND_COLOR);
+
+            for (List<ProfilingData> profilingDataList : this.lineNumber2profilingData) {
+                int y = this.getY(profilingDataList.get(0)) + yOffset;
+
+                graphics2D.fillRect(xOffset, y, availableWidth, BAR_HEIGHT);
             }
         }
 
-        private void drawGreenBars(Graphics2D g, final int xOffset, final int yOffset) {
-            g.setColor(Color.GREEN.darker().darker());
-            for (List<ProfilingData> pds : this.lineNumber2profilingData) {
-                int y = this.getY(pds.get(0)) + yOffset;
-                for (ProfilingData pd : pds) {
-                    int x = (int) (BAR_WIDTH * this.factor(pd.getInvocationStartTime()));
-                    int width = (int) (BAR_WIDTH * this.factor(pd.getInvocationEndTime()) - x);
+        private void drawGreenBars(Graphics2D graphics2D, final int xOffset, final int yOffset, int availableWidth) {
+            graphics2D.setColor(ACTIVE_BAR_COLOR);
+
+            for (List<ProfilingData> profilingDataList : this.lineNumber2profilingData) {
+                int y = this.getY(profilingDataList.get(0)) + yOffset;
 
-                    g.fillRect(xOffset + x, y, width, 15);
+                for (ProfilingData eachProfilingData : profilingDataList) {
+                    int x = (int) (availableWidth * this.factor(eachProfilingData.getInvocationStartTime()));
+                    int width = (int) (availableWidth * this.factor(eachProfilingData.getInvocationEndTime()) - x);
+
+                    graphics2D.fillRect(xOffset + x, y, width, BAR_HEIGHT);
                 }
             }
         }
 
-        private void drawOrangeBars(Graphics2D g, final int xOffset, final int yOffset) {
-            g.setColor(Color.ORANGE);
-            for (List<ProfilingData> pds : this.lineNumber2profilingData) {
-                int y = this.getY(pds.get(0)) + yOffset;
+        private void drawOrangeBars(Graphics2D graphics2D, final int xOffset, final int yOffset, int availableWidth) {
+            graphics2D.setPaint(INACTIVE_BAR_COLOR);
+
+            for (List<ProfilingData> profilingDataList : this.lineNumber2profilingData) {
+                int y = this.getY(profilingDataList.get(0)) + yOffset;
 
-                for (ProfilingData pd : pds) {
-                    this.drawInactive(g, xOffset, y, pd.getChildren());
+                for (ProfilingData eachProfilingData : profilingDataList) {
+                    this.drawInactive(graphics2D, xOffset, y, eachProfilingData.getChildren(), availableWidth);
                 }
             }
         }
 
-        private void drawCallerLines(Graphics2D g, final int xOffset, final int yOffset) {
-            for (List<ProfilingData> pds : this.lineNumber2profilingData) {
-                for (ProfilingData pd : pds) {
-                    ProfilingData parent = pd.getParent();
-
+        private void drawCallerLines(Graphics2D graphics2D, final int xOffset, final int yOffset, int availableWidth) {
+            for (List<ProfilingData> profilingDataList : this.lineNumber2profilingData) {
+                for (ProfilingData eachProfilingData : profilingDataList) {
+                    ProfilingData parent = eachProfilingData.getParent();
                     if (parent == null) {
                         continue;
                     }
 
-                    int thisLine = this.getY(pd) + yOffset + 7;
-                    int parentLine = this.getY(parent) + yOffset + 7;
+                    int thisLine = this.getY(eachProfilingData) + yOffset + BAR_HEIGHT / 2;
+                    int parentLine = this.getY(parent) + yOffset + BAR_HEIGHT / 2;
 
-                    int startX = (int) (BAR_WIDTH * this.factor(pd.getInvocationStartTime()));
-                    int endX = (int) (BAR_WIDTH * this.factor(pd.getInvocationEndTime()));
-
-                    g.setColor(Color.DARK_GRAY);
-                    g.drawLine(startX + xOffset, thisLine, startX + xOffset, parentLine);
-
-                    g.setColor(Color.RED.darker());
-                    g.drawLine(endX + xOffset, thisLine, endX + xOffset, parentLine);
+                    graphics2D.setColor(Color.DARK_GRAY);
+                    int startX = (int) (availableWidth * this.factor(eachProfilingData.getInvocationStartTime()));
+                    graphics2D.drawLine(startX + xOffset, thisLine, startX + xOffset, parentLine);
+
+                    graphics2D.setColor(Color.RED.darker());
+                    int endX = (int) (availableWidth * this.factor(eachProfilingData.getInvocationEndTime()));
+                    graphics2D.drawLine(endX + xOffset, thisLine, endX + xOffset, parentLine);
                 }
             }
         }
 
-        private void drawExecutionTimeStrings(Graphics2D g, final int xOffset) {
-            g.setColor(Color.BLACK);
-            for (List<ProfilingData> pds : this.lineNumber2profilingData) {
-                double executionTime = 0;
-                for (ProfilingData pd : pds) {
-                    executionTime += pd.getExecutionMillis();
-                }
+        private double getExecutionTime(List<ProfilingData> profilingDataList) {
+            double executionTime = 0;
 
-                String et = String.format(Locale.US, "%.3fms", executionTime);
-                g.drawString(et, xOffset + BAR_WIDTH + 20, this.getY(pds.get(0)));
+            for (ProfilingData eachProfilingData : profilingDataList) {
+                executionTime += eachProfilingData.getExecutionMillis();
             }
+
+            return executionTime;
         }
 
-        private String adaptToMaxWidth(FontMetrics metrics, String displayName) {
-            String s = displayName;
-            while (metrics.stringWidth(s) > this.MAX_STRING_WIDTH) {
-                int length = s.length();
-                String start = s.substring(0, length / 2 - 1);
-                String end = s.substring(length / 2 + 1, length);
-                s = start + end;
+        private String adaptToMaxWidth(FontMetrics metrics, String text) {
+            String currentText = text;
+
+            while (metrics.stringWidth(currentText) > MAX_DISPLAY_NAME_WIDTH) {
+                int length = currentText.length();
+                String start = currentText.substring(0, length / 2 - 1);
+                String end = currentText.substring(length / 2 + 1, length);
+                currentText = start + end;
             }
 
-            if (!s.equals(displayName)) {
-                int length = s.length();
-                String start = s.substring(0, length / 2);
-                String end = s.substring(length / 2, length);
-                s = start + "..." + end;
+            if (!currentText.equals(text)) {
+                int length = currentText.length();
+                String start = currentText.substring(0, length / 2);
+                String end = currentText.substring(length / 2, length);
+                currentText = start + "..." + end;
             }
 
-            return s;
+            return currentText;
         }
 
-        private void drawInactive(Graphics g, int xOffset, int y, List<ProfilingData> children) {
-            for (ProfilingData pd : children) {
-                int x = (int) (BAR_WIDTH * this.factor(pd.getInvocationStartTime()));
-                int width = (int) (BAR_WIDTH * this.factor(pd.getInvocationEndTime()) - x);
+        private void drawInactive(Graphics2D graphics2D, int xOffset, int y, List<ProfilingData> profilingData,
+                int availableWidth) {
+            for (ProfilingData eachProfilingData : profilingData) {
+                int x = (int) (availableWidth * this.factor(eachProfilingData.getInvocationStartTime()));
+                int width = (int) (availableWidth * this.factor(eachProfilingData.getInvocationEndTime()) - x);
 
-                g.fillRect(xOffset + x, y, width, 15);
+                graphics2D.fillRect(xOffset + x, y, width, BAR_HEIGHT);
             }
         }
     }
 
-    private class ErrorMessageDrawer {
-
-        public void writeImage(OutputStream os) {
-            BufferedImage bufferedImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
-            Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
-            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-
-            String errormsg = String.format("Profiling Data for id '%s' couldn't be found.",
-                    ProfilingPngSerializer.this.id);
-
-            FontMetrics metrics = g.getFontMetrics();
-            int stringWidth = metrics.stringWidth(errormsg);
+    protected final static class ErrorMessageDrawer {
 
-            bufferedImage = new BufferedImage(stringWidth + 2, 20, BufferedImage.TYPE_INT_ARGB);
-            g = (Graphics2D) bufferedImage.getGraphics();
-            g.setBackground(Color.WHITE);
-            g.setColor(Color.BLACK);
-            g.drawString(errormsg, 1, 15);
-            g.dispose();
+        private static final int LINE_HEIGHT = 20;
+        private static final int MESSAGE_X_OFFSET = 1;
+        private static final int MESSAGE_Y_OFFSET = 15;
+
+        public void writeImage(String id, OutputStream outputStream) {
+            String errorMessage = String.format("Profiling Data for id '%s' couldn't be found.", id);
+
+            int messageWidth = this.getWidth(errorMessage);
+
+            BufferedImage bufferedImage = new BufferedImage(messageWidth + 2 * MESSAGE_X_OFFSET, LINE_HEIGHT,
+                    BufferedImage.TYPE_INT_ARGB);
+            Graphics2D graphics2D = bufferedImage.createGraphics();
+            graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+            graphics2D.setBackground(Color.WHITE);
+            graphics2D.setColor(Color.BLACK);
+            graphics2D.drawString(errorMessage, MESSAGE_X_OFFSET, MESSAGE_Y_OFFSET);
+            graphics2D.dispose();
 
             try {
-                ImageIO.write(bufferedImage, "png", os);
+                ImageIO.write(bufferedImage, "png", outputStream);
             } catch (IOException e) {
-                throw new RuntimeException(e);
+                throw new ProcessingException("Failed to generate error image", e);
             }
         }
+
+        private int getWidth(String text) {
+            BufferedImage bufferedImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+            Graphics2D graphics2D = bufferedImage.createGraphics();
+            graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+            FontMetrics metrics = graphics2D.getFontMetrics();
+            return metrics.stringWidth(text);
+        }
     }
 
     public CacheKey constructCacheKey() {
-        return new ParameterCacheKey("id", this.id);
+        CompoundCacheKey compoundCacheKey = new CompoundCacheKey();
+
+        compoundCacheKey.addCacheKey(new ParameterCacheKey("id", this.id));
+        compoundCacheKey.addCacheKey(new ParameterCacheKey("width", String.valueOf(this.imageWidth)));
+
+        return compoundCacheKey;
     }
 }

Modified: cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/spring/AutomaticProfilerInstaller.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/spring/AutomaticProfilerInstaller.java?rev=1158449&r1=1158448&r2=1158449&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/spring/AutomaticProfilerInstaller.java (original)
+++ cocoon/cocoon3/trunk/cocoon-profiling/src/main/java/org/apache/cocoon/profiling/spring/AutomaticProfilerInstaller.java Tue Aug 16 21:18:20 2011
@@ -64,8 +64,8 @@ public class AutomaticProfilerInstaller 
      * first.
      */
     public void installProfilers() {
-        for (Profiler<?> p : this.profilers.values()) {
-            this.install(p);
+        for (Profiler<?> profiler : this.profilers.values()) {
+            this.install(profiler);
         }
     }