001: /*
002: * Beryl - A web platform based on XML, XSLT and Java
003: * This file is part of the Beryl XML GUI
004: *
005: * Copyright (C) 2004 Wenzel Jakob <wazlaf@tigris.org>
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011:
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-3107 USA
020: */
021:
022: package org.beryl.gui;
023:
024: import java.awt.Color;
025: import java.awt.Dimension;
026: import java.awt.Font;
027: import java.awt.Point;
028:
029: import javax.swing.BorderFactory;
030: import javax.swing.JFrame;
031: import javax.swing.ListSelectionModel;
032: import javax.swing.SwingConstants;
033: import javax.swing.border.Border;
034:
035: import org.w3c.dom.Element;
036: import org.w3c.dom.NodeList;
037:
038: /**
039: * Known property types:
040: *
041: * <tt>int</tt> - Integer
042: * <tt>float</tt> - Float
043: * <tt>double</tt> - Double
044: * <tt>bool</tt> - Boolean
045: * <tt>long</tt> - Long
046: * <tt>string</tt> - String
047: * <tt>istring></tt> - Internationalized string
048: * <tt>icon</tt> - Icon
049: * <tt>font</tt> - Font
050: * <tt>iicon</tt> - Internationalized icon
051: * <tt>dimension</tt> - Dimension data (width, height)
052: * <tt>point</tt> - Point data (x, y)
053: * <tt>color</tt> - Color
054: * <tt>border</tt> - Swing border
055: * <tt>enum</tt> - Swing constants
056: */
057:
058: public class PropertyFactory {
059: private static PropertyFactory factoryInstance = new PropertyFactory();
060:
061: private PropertyFactory() {
062: }
063:
064: public Object constructProperty(Element dataNode)
065: throws GUIException {
066: String name = dataNode.getAttribute("name");
067: String type = dataNode.getAttribute("type");
068:
069: if ("istring".equals(type) || "".equals(type)) {
070: if (name.equals("key") || name.equals("valuekey")
071: || name.equals("indexkey"))
072: return XMLUtils.extractTextChildren(dataNode);
073: else
074: return InternationalizationManager.getString(XMLUtils
075: .extractTextChildren(dataNode));
076: } else if ("string".equals(type)) {
077: return XMLUtils.extractTextChildren(dataNode);
078: } else if ("iicon".equals(type)) {
079: return ImageIconFactory.getIcon(InternationalizationManager
080: .getString(XMLUtils.extractTextChildren(dataNode)));
081: } else if ("icon".equals(type)) {
082: return ImageIconFactory.getIcon(XMLUtils
083: .extractTextChildren(dataNode));
084: } else if ("int".equals(type)) {
085: try {
086: return new Integer(XMLUtils
087: .extractTextChildren(dataNode));
088: } catch (NumberFormatException e) {
089: throw new GUIException("Cannot parse integer data", e);
090: }
091: } else if ("float".equals(type)) {
092: try {
093: return new Float(XMLUtils.extractTextChildren(dataNode));
094: } catch (NumberFormatException e) {
095: throw new GUIException("Cannot parse float data", e);
096: }
097: } else if ("double".equals(type)) {
098: try {
099: return new Double(XMLUtils
100: .extractTextChildren(dataNode));
101: } catch (NumberFormatException e) {
102: throw new GUIException("Cannot parse double data", e);
103: }
104: } else if ("long".equals(type)) {
105: try {
106: return new Long(XMLUtils.extractTextChildren(dataNode));
107: } catch (NumberFormatException e) {
108: throw new GUIException("Cannot parse long data", e);
109: }
110: } else if ("bool".equals(type)) {
111: return new Boolean(XMLUtils.extractTextChildren(dataNode));
112: } else if ("border".equals(type)) {
113: return constructBorder(dataNode);
114: } else if ("dimension".equals(type)) {
115: return constructDimension(dataNode);
116: } else if ("point".equals(type)) {
117: return constructPoint(dataNode);
118: } else if ("enum".equals(type)) {
119: return constructEnum(dataNode);
120: } else if ("color".equals(type)) {
121: return constructColor(dataNode);
122: } else if ("font".equals(type)) {
123: return constructFont(dataNode);
124: }
125: throw new GUIException("Unknown property type [" + type + "]");
126: }
127:
128: private Dimension constructDimension(Element dataNode)
129: throws GUIException {
130: NodeList widthNodes = dataNode.getElementsByTagName("width");
131: NodeList heightNodes = dataNode.getElementsByTagName("height");
132:
133: if (widthNodes.getLength() == 1 && heightNodes.getLength() == 1) {
134: try {
135: int width = Integer.parseInt(XMLUtils
136: .getStringFromChild(dataNode, "width"));
137: int height = Integer.parseInt(XMLUtils
138: .getStringFromChild(dataNode, "height"));
139: return new Dimension(width, height);
140: } catch (NumberFormatException e) {
141: throw new GUIException("Cannot parse dimension data", e);
142: }
143: } else {
144: throw new GUIException("Invalid dimension data");
145: }
146: }
147:
148: private Point constructPoint(Element dataNode) throws GUIException {
149: NodeList xNodes = dataNode.getElementsByTagName("x");
150: NodeList yNodes = dataNode.getElementsByTagName("y");
151:
152: if (xNodes.getLength() == 1 && yNodes.getLength() == 1) {
153: try {
154: int x = Integer.parseInt(XMLUtils.getStringFromChild(
155: dataNode, "x"));
156: int y = Integer.parseInt(XMLUtils.getStringFromChild(
157: dataNode, "y"));
158: return new Point(x, y);
159: } catch (NumberFormatException e) {
160: throw new GUIException("Cannot parse dimension data", e);
161: }
162: } else {
163: throw new GUIException("Invalid dimension data");
164: }
165: }
166:
167: private Color constructColor(Element dataNode) throws GUIException {
168: String color = XMLUtils.extractTextChildren(dataNode);
169: if (color.length() == 7 && color.startsWith("#")) {
170: try {
171: int r = Integer.parseInt(color.substring(1, 3), 16);
172: int g = Integer.parseInt(color.substring(3, 5), 16);
173: int b = Integer.parseInt(color.substring(5, 7), 16);
174: return new Color(r, g, b);
175: } catch (NumberFormatException e) {
176: throw new GUIException("Invalid color data", e);
177: }
178: } else {
179: throw new GUIException("Invalid color syntax");
180: }
181: }
182:
183: private Font constructFont(Element dataNode) throws GUIException {
184: NodeList nameNodes = dataNode.getElementsByTagName("name");
185: NodeList styleNodes = dataNode.getElementsByTagName("style");
186: NodeList sizeNodes = dataNode.getElementsByTagName("size");
187:
188: if (nameNodes.getLength() == 1 && styleNodes.getLength() == 1
189: && sizeNodes.getLength() == 1) {
190: try {
191: int size = Integer.parseInt(XMLUtils
192: .getStringFromChild(dataNode, "size"));
193: String name = XMLUtils.getStringFromChild(dataNode,
194: "name");
195: String styleName = XMLUtils.getStringFromChild(
196: dataNode, "style");
197: int style = Font.PLAIN;
198: if (styleName.equals("bold"))
199: style = Font.BOLD;
200: else if (styleName.equals("italic"))
201: style = Font.ITALIC;
202: else if (styleName.equals("bolditalic"))
203: style = Font.BOLD | Font.ITALIC;
204: return new Font(name, style, size);
205: } catch (NumberFormatException e) {
206: throw new GUIException("Cannot parse font data", e);
207: }
208: } else {
209: throw new GUIException("Invalid font data");
210: }
211: }
212:
213: private Border constructBorder(Element dataNode)
214: throws GUIException {
215: String borderType = dataNode.getAttribute("border");
216: try {
217: if (borderType.equals("empty")) {
218: int top = Integer.parseInt(XMLUtils.getStringFromChild(
219: dataNode, "top"));
220: int bottom = Integer.parseInt(XMLUtils
221: .getStringFromChild(dataNode, "bottom"));
222: int left = Integer.parseInt(XMLUtils
223: .getStringFromChild(dataNode, "left"));
224: int right = Integer.parseInt(XMLUtils
225: .getStringFromChild(dataNode, "right"));
226: return BorderFactory.createEmptyBorder(top, left,
227: bottom, right);
228: } else if (borderType.equals("titled")) {
229: return BorderFactory
230: .createTitledBorder(InternationalizationManager
231: .getString(XMLUtils.getStringFromChild(
232: dataNode, "title")));
233: } else if (borderType.equals("none")) {
234: return BorderFactory.createEmptyBorder();
235: } else if (borderType.equals("lowered")) {
236: return BorderFactory.createLoweredBevelBorder();
237: } else if (borderType.equals("raised")) {
238: return BorderFactory.createRaisedBevelBorder();
239: } else if (borderType.equals("etched")) {
240: return BorderFactory.createEtchedBorder();
241: } else {
242: throw new GUIException("Unknown border type ["
243: + borderType + "]");
244: }
245: } catch (NumberFormatException e) {
246: throw new GUIException("Invalid border data", e);
247: }
248: }
249:
250: private Integer constructEnum(Element dataNode) throws GUIException {
251: String name = XMLUtils.extractTextChildren(dataNode);
252: if (name.equals("center"))
253: return new Integer(SwingConstants.CENTER);
254: else if (name.equals("left") || name.equals("west"))
255: return new Integer(SwingConstants.LEFT);
256: else if (name.equals("right") || name.equals("east"))
257: return new Integer(SwingConstants.RIGHT);
258: else if (name.equals("top") || name.equals("north"))
259: return new Integer(SwingConstants.TOP);
260: else if (name.equals("bottom") || name.equals("south"))
261: return new Integer(SwingConstants.BOTTOM);
262: else if (name.equals("nothing"))
263: return new Integer(JFrame.DO_NOTHING_ON_CLOSE);
264: else if (name.equals("dispose"))
265: return new Integer(JFrame.DISPOSE_ON_CLOSE);
266: else if (name.equals("exit"))
267: return new Integer(JFrame.EXIT_ON_CLOSE);
268: else if (name.equals("single"))
269: return new Integer(ListSelectionModel.SINGLE_SELECTION);
270: else if (name.equals("single_interval"))
271: return new Integer(
272: ListSelectionModel.SINGLE_INTERVAL_SELECTION);
273: else if (name.equals("multiple_interval"))
274: return new Integer(
275: ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
276: else
277: throw new GUIException("Unknown enum name [" + name + "]");
278: }
279:
280: public static PropertyFactory getInstance() {
281: return factoryInstance;
282: }
283: }
|