1 /*
2  * Copyright 2008-2019 by Emeric Vernat
3  *
4  *     This file is part of Java Melody.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package net.bull.javamelody.internal.web.pdf;
19
20 import java.awt.Graphics;
21 import java.awt.image.BufferedImage;
22 import java.io.IOException;
23
24 import javax.imageio.ImageIO;
25
26 import net.bull.javamelody.internal.common.Parameters;
27 import net.bull.javamelody.internal.model.JavaInformations;
28
29 /**
30  * Construction d'une barre de pourcentage.
31  * @author Emeric Vernat
32  */

33 public final class Bar {
34     // constantes pour l'affichage d'une barre avec pourcentage
35     private static final double MIN_VALUE = 0;
36     private static final double MAX_VALUE = 100;
37     private static final int PARTIAL_BLOCKS = 5;
38     private static final int FULL_BLOCKS = 10;
39     private static final double UNIT_SIZE = (MAX_VALUE - MIN_VALUE)
40             / (FULL_BLOCKS * PARTIAL_BLOCKS);
41
42     private final double percentValue;
43     private final BufferedImage image;
44     private final Graphics graphics;
45     private int x; // initialisé à 0
46     private final boolean alertOnHighUsage;
47
48     private Bar(double percentValue, boolean alertOnHighUsage) {
49         super();
50         this.percentValue = percentValue;
51         this.alertOnHighUsage = alertOnHighUsage;
52         if (alertOnHighUsage) {
53             this.image = new BufferedImage(130, 14, BufferedImage.TYPE_INT_ARGB);
54         } else {
55             this.image = new BufferedImage(106, 10, BufferedImage.TYPE_INT_ARGB);
56         }
57         this.graphics = image.getGraphics();
58     }
59
60     public static BufferedImage toBar(double percentValue) throws IOException {
61         final Bar bar = new Bar(percentValue, false);
62         bar.draw();
63         bar.graphics.dispose();
64         return bar.image;
65     }
66
67     public static BufferedImage toBarWithAlert(double percentValue) throws IOException {
68         final Bar bar = new Bar(percentValue,
69                 percentValue >= JavaInformations.HIGH_USAGE_THRESHOLD_IN_PERCENTS);
70         bar.draw();
71         bar.graphics.dispose();
72         return bar.image;
73     }
74
75     // méthode inspirée de VisualScoreTag dans LambdaProbe/JStripe (Licence GPL)
76     private void draw() throws IOException { // NOPMD
77         assert x == 0;
78         final double myPercent = Math.max(Math.min(percentValue, 100d), 0d);
79         final int fullBlockCount = (int) Math.floor(myPercent / (UNIT_SIZE * PARTIAL_BLOCKS));
80         final int partialBlockIndex = (int) Math
81                 .floor((myPercent - fullBlockCount * UNIT_SIZE * PARTIAL_BLOCKS) / UNIT_SIZE);
82
83         addImage(getBarImage(fullBlockCount > 0 || partialBlockIndex > 0 ? "a" : "a0"));
84
85         final BufferedImage fullBody = getBarImage(String.valueOf(PARTIAL_BLOCKS));
86         for (int i = 0; i < fullBlockCount; i++) {
87             addImage(fullBody);
88         }
89
90         if (partialBlockIndex > 0) {
91             final BufferedImage partialBody = getBarImage(String.valueOf(partialBlockIndex));
92             addImage(partialBody);
93         }
94
95         final int emptyBlocks = FULL_BLOCKS - fullBlockCount - (partialBlockIndex > 0 ? 1 : 0);
96         final BufferedImage emptyBody = getBarImage(String.valueOf(0));
97         for (int i = 0; i < emptyBlocks; i++) {
98             addImage(emptyBody);
99         }
100
101         addImage(getBarImage(fullBlockCount == FULL_BLOCKS ? "b" : "b0"));
102
103         if (alertOnHighUsage) {
104             x += 8;
105             graphics.drawImage(getImage("alert.png"), x, 0, null);
106         }
107     }
108
109     private void addImage(BufferedImage img) {
110         graphics.drawImage(img, x, alertOnHighUsage ? 4 : 0, null);
111         x += img.getWidth();
112     }
113
114     private static BufferedImage getBarImage(String key) throws IOException {
115         return getImage("bar/rb_" + key + ".gif");
116     }
117
118     private static BufferedImage getImage(String fileName) throws IOException {
119         // ici, ne pas utiliser Toolkit.createImage et surtout pas ImageIcon (sur un serveur)
120         return ImageIO.read(Bar.class.getResource(Parameters.getResourcePath(fileName)));
121     }
122 }
123