Coverage Report - com.liquidatom.derbyscore.theme.Theme
 
Classes in this File Line Coverage Branch Coverage Complexity
Theme
33%
24/71
12%
3/24
2
 
 1  
 package com.liquidatom.derbyscore.theme;
 2  
 
 3  
 import com.liquidatom.derbyscore.PicoContainerFactory;
 4  
 import com.liquidatom.derbyscore.domain.Bout;
 5  
 import java.awt.Font;
 6  
 import java.awt.Graphics2D;
 7  
 import java.awt.GraphicsConfiguration;
 8  
 import java.awt.GraphicsEnvironment;
 9  
 import java.awt.Transparency;
 10  
 import java.awt.image.BufferedImage;
 11  
 import java.net.URL;
 12  
 import java.util.ArrayList;
 13  
 import java.util.Collection;
 14  
 import java.util.Collections;
 15  
 import java.util.HashMap;
 16  
 import java.util.List;
 17  
 import java.util.Map;
 18  
 import java.util.Map.Entry;
 19  
 import java.util.concurrent.locks.Lock;
 20  
 import java.util.concurrent.locks.ReentrantLock;
 21  
 import javax.annotation.concurrent.GuardedBy;
 22  
 import javax.script.ScriptContext;
 23  
 import javax.script.ScriptEngine;
 24  
 import javax.script.ScriptEngineManager;
 25  
 import org.picocontainer.MutablePicoContainer;
 26  
 
 27  
 /**
 28  
  *
 29  
  * @author Russell Francis (russ@metro-six.com)
 30  
  */
 31  
 public class Theme {
 32  
 
 33  
     final private URL themeDefinitionURL;
 34  
 
 35  9
     @GuardedBy("itself")
 36  
     final private Map<String, Font> fonts = Collections.synchronizedMap(new HashMap<String, Font>());
 37  
 
 38  
     // *** We must always synchronize images before fonts if we need to synchronize on both.
 39  9
     @GuardedBy("itself")
 40  
     final private Map<String, BufferedImage> images = Collections.synchronizedMap(new HashMap<String, BufferedImage>());
 41  
 
 42  
     // *** We must always synchronize elements before images / fonts if we require synchronization on both.
 43  9
     @GuardedBy("itself")
 44  
     final private List<ThemeElement> elements = Collections.synchronizedList(new ArrayList<ThemeElement>());
 45  
 
 46  9
     @GuardedBy("javascriptEngineLock")
 47  
     final private ScriptEngine javascriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");
 48  9
     final private Lock javascriptEngineLock = new ReentrantLock();
 49  
 
 50  
     protected Theme() {
 51  3
         this(null);
 52  3
     }
 53  
 
 54  9
     public Theme(final URL themeDefinitionURL) {
 55  9
         this.themeDefinitionURL = themeDefinitionURL;
 56  9
     }
 57  
     
 58  
     protected GraphicsConfiguration getDefaultConfiguration() {
 59  0
         return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
 60  
     }
 61  
 
 62  
     protected BufferedImage toCompatibleImage(final BufferedImage img, final int transparency, GraphicsConfiguration gc) {
 63  0
         if (gc == null) {
 64  0
             gc = getDefaultConfiguration();
 65  
         }
 66  0
         int w = img.getWidth();
 67  0
         int h = img.getHeight();
 68  0
         BufferedImage result = gc.createCompatibleImage(w, h, transparency);
 69  0
         Graphics2D g2 = result.createGraphics();
 70  0
         g2.drawRenderedImage(img, null);
 71  0
         g2.dispose();
 72  0
         return result;
 73  
     }
 74  
 
 75  
     public Collection<ThemeElement> getThemeElements() {
 76  0
         return Collections.unmodifiableCollection(elements);
 77  
     }
 78  
 
 79  
     public BufferedImage getBackdrop() {
 80  0
         synchronized (elements) {
 81  0
             for (ThemeElement e : elements) {
 82  0
                 if (e instanceof ImageElement) {
 83  0
                     return images.get(((ImageElement)e).getImgRef());
 84  
                 }
 85  
             }
 86  0
         }
 87  0
         return null;
 88  
     }
 89  
 
 90  
     public Font getFont(final String id) {
 91  15
         return fonts.get(id);
 92  
     }
 93  
 
 94  
     public BufferedImage getImage(String id) {
 95  0
         if (id.equals("team-a-logo")) {
 96  0
             return getBout().getTeamA().getImage();
 97  
         }
 98  0
         else if (id.equals("team-b-logo")) {
 99  0
             return getBout().getTeamB().getImage();
 100  
         }
 101  
 
 102  0
         return images.get(id);
 103  
     }
 104  
 
 105  
     protected Bout getBout() {
 106  0
         PicoContainerFactory picoContainerFactory = PicoContainerFactory.getInstance();
 107  0
         MutablePicoContainer pico = picoContainerFactory.get();
 108  0
         return pico.getComponent(Bout.class);
 109  
     }
 110  
 
 111  
     public void addResource(final String id, final Font font) {
 112  3
         synchronized (images) {
 113  3
             synchronized (fonts) {
 114  3
                 if (fonts.containsKey(id) || images.containsKey(id)) {
 115  0
                     throw new IllegalStateException("The id's for resources must be unique '" + id + "' is duplicated!");
 116  
                 }
 117  3
                 fonts.put(id, font.deriveFont((float)300));
 118  3
             }
 119  3
         }
 120  3
     }
 121  
 
 122  
     public void addResource(final String id, final BufferedImage img) {
 123  0
         addResource(id, img, Transparency.OPAQUE);
 124  0
     }
 125  
 
 126  
     public void addResource(final String id, final BufferedImage img, final int transparency) {
 127  0
         synchronized (images) {
 128  0
             synchronized (fonts) {
 129  0
                 if (fonts.containsKey(id) || images.containsKey(id)) {
 130  0
                     throw new IllegalStateException("The id's for resources must be unique '" + id + "' is duplicated!");
 131  
                 }
 132  
 
 133  0
                 images.put(id, toCompatibleImage(img, transparency, getDefaultConfiguration()));
 134  0
             }
 135  0
         }
 136  0
     }
 137  
 
 138  
     public boolean addElement(final ThemeElement element) {
 139  0
         return elements.add(element);
 140  
     }
 141  
 
 142  
     public URL getThemeDefinitionURL() {
 143  0
         return themeDefinitionURL;
 144  
     }
 145  
 
 146  
     public String getBase() {
 147  0
         String externalForm = getThemeDefinitionURL().toExternalForm();
 148  0
         int lastIndexOfSlash = externalForm.lastIndexOf("/");
 149  0
         return externalForm.substring(0, lastIndexOfSlash) + "/";
 150  
     }
 151  
 
 152  
     protected ScriptEngine acquireJavascriptEngine(final Map<String, Object> scope) {
 153  6
         javascriptEngineLock.lock();
 154  
 
 155  6
         if (scope != null) {
 156  0
             for (final Entry<String,Object> entry : scope.entrySet()) {
 157  0
                 final String key = entry.getKey();
 158  0
                 if (key != null) {
 159  0
                     final Object value = entry.getValue();
 160  0
                     javascriptEngine.put(key, value);
 161  
                 }
 162  0
             }
 163  
         }
 164  
 
 165  6
         return javascriptEngine;
 166  
     }
 167  
 
 168  
     protected void releaseJavascriptEngine() {
 169  6
         javascriptEngine.setBindings(javascriptEngine.createBindings(), ScriptContext.ENGINE_SCOPE);
 170  6
         javascriptEngineLock.unlock();
 171  6
     }
 172  
 
 173  
 }