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 | |
|
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 | |
|
39 | 9 | @GuardedBy("itself") |
40 | |
final private Map<String, BufferedImage> images = Collections.synchronizedMap(new HashMap<String, BufferedImage>()); |
41 | |
|
42 | |
|
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 | |
} |