Coverage Report - com.liquidatom.derbyscore.theme.ThemeBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
ThemeBuilder
0%
0/100
0%
0/36
4.571
 
 1  
 package com.liquidatom.derbyscore.theme;
 2  
 
 3  
 import com.sun.org.apache.xerces.internal.parsers.DOMParser;
 4  
 import java.awt.Color;
 5  
 import java.awt.Font;
 6  
 import java.awt.FontFormatException;
 7  
 import java.awt.Rectangle;
 8  
 import java.awt.Transparency;
 9  
 import java.awt.image.BufferedImage;
 10  
 import java.io.IOException;
 11  
 import java.io.InputStream;
 12  
 import java.net.URL;
 13  
 import javax.annotation.concurrent.Immutable;
 14  
 import javax.annotation.concurrent.ThreadSafe;
 15  
 import javax.imageio.ImageIO;
 16  
 import org.w3c.dom.Document;
 17  
 import org.w3c.dom.Element;
 18  
 import org.w3c.dom.Node;
 19  
 import org.w3c.dom.NodeList;
 20  
 import org.xml.sax.InputSource;
 21  
 import org.xml.sax.SAXException;
 22  
 
 23  
 /**
 24  
  *
 25  
  * @author Russell Francis (russ@metro-six.com)
 26  
  */
 27  
 @ThreadSafe
 28  
 @Immutable
 29  0
 public class ThemeBuilder {
 30  
 
 31  0
     static private final Color DEFAULT_FONT_COLOR = new Color(0, 255, 0);
 32  
 
 33  
     /**
 34  
      * Read the input stream which contains the theme.xml definition for the theme.
 35  
      * 
 36  
      * @return A newly constructed Theme instance.
 37  
      */
 38  
     public Theme buildTheme(final URL themeDefinitionURL) throws SAXException, IOException, FontFormatException {
 39  0
         Theme theme = new Theme(themeDefinitionURL);
 40  0
         InputStream themeStream = themeDefinitionURL.openStream();
 41  
         try {
 42  0
             InputSource themeSource = new InputSource(themeStream);
 43  0
             DOMParser parser = new DOMParser();
 44  0
             parser.parse(themeSource);
 45  0
             Document doc = parser.getDocument();
 46  
 
 47  0
             loadResources(doc, theme);
 48  0
             loadLayout(doc, theme);
 49  
 
 50  0
             return theme;
 51  
         }
 52  
         finally {
 53  0
             themeStream.close();
 54  
         }
 55  
     }
 56  
 
 57  
     private void loadResources(final Document doc, final Theme theme) throws IOException, FontFormatException {
 58  0
         NodeList nodes = doc.getElementsByTagName("resources");
 59  0
         if (nodes.getLength() != 1) {
 60  0
             throw new IllegalStateException("May only define one resources section in the theme.xml definition file.");
 61  
         }
 62  0
         Node resources = nodes.item(0);
 63  0
         nodes = resources.getChildNodes();
 64  0
         for (int i = 0; i < nodes.getLength(); ++i) {
 65  0
             Node resource = nodes.item(i);
 66  0
             if (resource instanceof Element) {
 67  0
                 Element element = (Element)resource;
 68  0
                 if ("image".equals(element.getTagName())) {
 69  0
                     String id = element.getAttribute("id");
 70  0
                     String src = element.getAttribute("src");
 71  0
                     String transparency = element.getAttribute("transparency").toLowerCase();
 72  0
                     int transparencyValue = Transparency.OPAQUE;
 73  0
                     if ("translucent".equals(transparency)) {
 74  0
                         transparencyValue = Transparency.TRANSLUCENT;
 75  
                     }
 76  0
                     else if ("bitmask".equals(transparency)) {
 77  0
                         transparencyValue = Transparency.BITMASK;
 78  
                     }
 79  0
                     BufferedImage image = loadImage(new URL(theme.getBase() + src));
 80  0
                     theme.addResource(id, image, transparencyValue);
 81  0
                 }
 82  0
                 else if ("font".equals(element.getTagName())) {
 83  0
                     String id = element.getAttribute("id");
 84  0
                     String src = element.getAttribute("src");
 85  0
                     Font font = loadFont(new URL(theme.getBase() + src));
 86  0
                     theme.addResource(id, font);
 87  
                 }
 88  
             }
 89  
         }
 90  0
     }
 91  
 
 92  
     private void loadLayout(final Document doc, final Theme theme) {
 93  0
         NodeList nodes = doc.getElementsByTagName("layout");
 94  0
         if (nodes.getLength() != 1) {
 95  0
             throw new IllegalStateException("May only define one layout section within the definition.");
 96  
         }
 97  0
         Node resources = nodes.item(0);
 98  0
         nodes = resources.getChildNodes();
 99  0
         for (int i = 0; i < nodes.getLength(); ++i) {
 100  0
             Node node = nodes.item(i);
 101  0
             if (node instanceof Element) {
 102  0
                 Element element = (Element)node;
 103  0
                 if ("text".equals(element.getTagName())) {
 104  0
                     Rectangle position = readPosition(element);
 105  0
                     Element fontElement = (Element)element.getElementsByTagName("font").item(0);
 106  0
                     String fontRef = fontElement.getAttribute("ref");
 107  0
                     String fontColor = fontElement.getAttribute("color");
 108  
 
 109  0
                     Element value = (Element)element.getElementsByTagName("value").item(0);
 110  0
                     String valueString = value.getTextContent();
 111  
 
 112  0
                     String visibleCondition = null;
 113  0
                     NodeList nodeList = element.getElementsByTagName("condition");
 114  0
                     if (nodeList.getLength() == 1) {
 115  0
                         Element conditionElement = (Element) nodeList.item(0);
 116  0
                         visibleCondition = conditionElement.getTextContent();
 117  
                     }
 118  
 
 119  0
                     theme.addElement(
 120  
                         new TextElement(theme, visibleCondition, position, valueString, fontRef, parseColor(fontColor)));
 121  0
                 }
 122  0
                 else if ("image".equals(element.getTagName())) {
 123  0
                     Rectangle position = readPosition(element);
 124  0
                     String imgRef = element.getAttribute("ref");
 125  0
                     String conditionJs = null;
 126  0
                     NodeList nodeList = element.getElementsByTagName("condition");
 127  0
                     if (nodeList.getLength() == 1) {
 128  0
                         Element conditionElement = (Element) nodeList.item(0);
 129  0
                         conditionJs = conditionElement.getTextContent();
 130  
                     }
 131  
 
 132  0
                     theme.addElement(new ImageElement(theme, conditionJs, position, imgRef));
 133  
                 }
 134  
             }
 135  
         }
 136  0
     }
 137  
 
 138  
     private Rectangle readPosition(final Element element) {
 139  0
         int x = Integer.parseInt(element.getAttribute("x"));
 140  0
         int y = Integer.parseInt(element.getAttribute("y"));
 141  
 
 142  0
         int width = 0;
 143  
         try {
 144  0
             width = Integer.parseInt(element.getAttribute("width"));
 145  
         }
 146  0
         catch (NumberFormatException e) {
 147  0
         }
 148  
 
 149  0
         int height = 0;
 150  
         try {
 151  0
             height = Integer.parseInt(element.getAttribute("height"));
 152  
         }
 153  0
         catch (NumberFormatException e) {
 154  0
         }
 155  
 
 156  0
         return new Rectangle(x, y, width, height);
 157  
     }
 158  
     
 159  
     private BufferedImage loadImage(final URL imageURL) throws IOException {
 160  0
         InputStream ins = imageURL.openStream();
 161  
         try {
 162  0
             return ImageIO.read(ins);
 163  
         }
 164  
         finally {
 165  0
             ins.close();
 166  
         }
 167  
     }
 168  
 
 169  
     private Font loadFont(final URL fontURL) throws FontFormatException, IOException {
 170  0
         InputStream ins = fontURL.openStream();
 171  
         try {
 172  0
             return Font.createFont(Font.TRUETYPE_FONT, ins);
 173  
         }
 174  
         finally {
 175  0
             ins.close();
 176  
         }
 177  
     }
 178  
 
 179  
     private Color parseColor(String color) {
 180  0
         Color result = null;
 181  0
         if (color != null) {
 182  0
             color = color.trim();
 183  0
             if (color.startsWith("#")) {
 184  0
                 color = color.substring(1);
 185  
             }
 186  0
             if (color.length() == 6) {
 187  0
                 int red = Integer.parseInt(color.substring(0, 2), 16);
 188  0
                 int green = Integer.parseInt(color.substring(2, 4), 16);
 189  0
                 int blue = Integer.parseInt(color.substring(4, 6), 16);
 190  0
                 result = new Color(red, green, blue);
 191  
             }
 192  
         }
 193  
 
 194  0
         return result == null ? DEFAULT_FONT_COLOR : result;
 195  
     }
 196  
 }