001: /* SwingML
002: * Copyright (C) 2002 SwingML Team
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: *
019: * Authors:
020: * Ezequiel Cuellar <ecuellar@crosslogic.com>
021: * Robert Morris <robertj@morris.net>
022: * Bram Stieperaere <bramez@users.sourceforge.net>
023: * Marcelo W. Lopez Cremona <marcelo_java@argentina.com>
024: */
025:
026: package org.swingml.xml;
027:
028: import java.awt.*;
029: import java.io.*;
030: import java.net.*;
031: import java.util.*;
032:
033: import javax.xml.parsers.*;
034:
035: import org.swingml.*;
036: import org.swingml.component.*;
037: import org.swingml.system.*;
038: import org.swingml.tablebrowser.ext.*;
039: import org.swingml.treetablebrowser.ext.*;
040: import org.swingml.xml.mapper.*;
041: import org.w3c.dom.*;
042: import org.xml.sax.*;
043:
044: public class MapperUtil {
045:
046: public static final Hashtable DEFAULT_MAPPERS;
047:
048: static {
049: DEFAULT_MAPPERS = new Hashtable();
050: DEFAULT_MAPPERS.put(Constants.PANEL, JPanelMapper.class);
051: DEFAULT_MAPPERS.put(Constants.MENUBAR, JMenuBarMapper.class);
052: DEFAULT_MAPPERS.put(Constants.MENU, JMenuMapper.class);
053: DEFAULT_MAPPERS.put(Constants.MENUITEM, JMenuItemMapper.class);
054: DEFAULT_MAPPERS
055: .put(Constants.SEPARATOR, JSeparatorMapper.class);
056: DEFAULT_MAPPERS.put(Constants.DIALOG, JDialogMapper.class);
057: DEFAULT_MAPPERS.put(Constants.FRAME, JFrameMapper.class);
058: DEFAULT_MAPPERS
059: .put(Constants.TEXTFIELD, JTextFieldMapper.class);
060: DEFAULT_MAPPERS.put(Constants.BUTTON, JButtonMapper.class);
061: DEFAULT_MAPPERS.put(Constants.TOOLBAR, JToolBarMapper.class);
062: DEFAULT_MAPPERS.put(Constants.TABBEDPANE,
063: JTabbedPaneMapper.class);
064: DEFAULT_MAPPERS.put(Constants.LABEL, JLabelMapper.class);
065: DEFAULT_MAPPERS.put(Constants.TREE, JTreeMapper.class);
066: DEFAULT_MAPPERS.put(Constants.NODE, NodeMapper.class);
067: DEFAULT_MAPPERS.put(Constants.TABLE, JTableMapper.class);
068: DEFAULT_MAPPERS.put(Constants.TC, TableColumnMapper.class);
069: DEFAULT_MAPPERS.put(Constants.TR, TableRowMapper.class);
070: DEFAULT_MAPPERS.put(Constants.TD, TableDataMapper.class);
071: DEFAULT_MAPPERS.put(Constants.COMBOBOX, JComboBoxMapper.class);
072: DEFAULT_MAPPERS.put(Constants.CHECKBOX, JCheckBoxMapper.class);
073: DEFAULT_MAPPERS.put(Constants.BUTTONGROUP,
074: ButtonGroupMapper.class);
075: DEFAULT_MAPPERS.put(Constants.RADIOBUTTON,
076: JRadioButtonMapper.class);
077: DEFAULT_MAPPERS.put(Constants.INTERNALFRAME,
078: JInternalFrameMapper.class);
079: DEFAULT_MAPPERS.put(Constants.TEXTAREA, JTextAreaMapper.class);
080: DEFAULT_MAPPERS.put(Constants.EDITORPANE,
081: JEditorPaneMapper.class);
082: DEFAULT_MAPPERS.put(Constants.OPTIONPANE,
083: JOptionPaneMapper.class);
084: DEFAULT_MAPPERS.put(Constants.LIST, JListMapper.class);
085: DEFAULT_MAPPERS.put(Constants.ITEM, ItemMapper.class);
086: DEFAULT_MAPPERS.put(Constants.LISTENER, ListenerMapper.class);
087: DEFAULT_MAPPERS.put(Constants.ACTION, ActionMapper.class);
088: DEFAULT_MAPPERS
089: .put(Constants.SPLITPANE, JSplitPaneMapper.class);
090: DEFAULT_MAPPERS.put(Constants.GRIDBAG_PANEL,
091: GridBagPanelMapper.class);
092: DEFAULT_MAPPERS.put(Constants.GRIDBAG_ROW,
093: GridBagRowMapper.class);
094: DEFAULT_MAPPERS.put(Constants.GRIDBAG_CELL,
095: GridBagCellMapper.class);
096: DEFAULT_MAPPERS.put(Constants.DEBUG, JDebugMapper.class);
097: DEFAULT_MAPPERS.put(Constants.EXTERNAL_ACTION,
098: ExternalActionMapper.class);
099: DEFAULT_MAPPERS.put(Constants.ACTION_PARAM,
100: ActionParamMapper.class);
101: DEFAULT_MAPPERS.put(Constants.PASSWORDTEXT,
102: JPasswordMapper.class);
103: DEFAULT_MAPPERS.put(Constants.DATASTORE, DataStoreMapper.class);
104: DEFAULT_MAPPERS.put(Constants.SLIDER, JSliderMapper.class);
105: DEFAULT_MAPPERS.put(Constants.DESKTOPPANE,
106: JDesktopPaneMapper.class);
107: DEFAULT_MAPPERS.put(Constants.FORMATTEDTEXTFIELD,
108: JFormattedTextFieldMapper.class);
109: DEFAULT_MAPPERS.put(Constants.SCROLLPANE,
110: JScrollPaneMapper.class);
111: DEFAULT_MAPPERS.put(Constants.CONTROLLER_ACTION,
112: ControllerActionMapper.class);
113:
114: // Error Handlers
115: DEFAULT_MAPPERS.put(Constants.ERROR_HANDLER,
116: ErrorHandlerMapper.class);
117: DEFAULT_MAPPERS.put(Constants.PARAMETER, ParameterMapper.class);
118:
119: // PROPERTIES
120: DEFAULT_MAPPERS.put(Constants.PROPERTIES, PropertyMapper.class);
121:
122: // ==================== - - - BROWSER MODIFICATIONS - - - ==================
123:
124: //-- TABLE BROWSER --
125: DEFAULT_MAPPERS.put(Constants.TABLEBROWSER,
126: TableBrowserMapper.class);
127: DEFAULT_MAPPERS.put(Constants.TBC,
128: TableBrowserColumnMapper.class);
129: DEFAULT_MAPPERS.put(Constants.TBR, TableBrowserRowMapper.class);
130: DEFAULT_MAPPERS
131: .put(Constants.TBD, TableBrowserDataMapper.class);
132:
133: //-- Start TreeTable BROWSER
134: DEFAULT_MAPPERS.put(Constants.TREETABLEBROWSER,
135: TreeTableBrowserMapper.class);
136: DEFAULT_MAPPERS.put(Constants.TREETABLEBROWSERCOLUMN,
137: TreeTableBrowserColumnMapper.class);
138: DEFAULT_MAPPERS.put(Constants.TREETABLEBROWSERDATA,
139: TreeTableBrowserDataMapper.class);
140: DEFAULT_MAPPERS.put(Constants.TREETABLEBROWSERNODE,
141: TreeTableBrowserNodeMapper.class);
142: DEFAULT_MAPPERS.put(Constants.TREETABLEBROWSERTREE,
143: TreeTableBrowserTreeMapper.class);
144: //--End TreeTable
145:
146: DEFAULT_MAPPERS.put(Constants.ICON, IconMapper.class);
147:
148: DEFAULT_MAPPERS.put(Constants.TEXT, TextMapper.class);
149:
150: }
151:
152: private final Map customMappers = new HashMap();
153:
154: public MapperUtil() {
155: }
156:
157: public Class addMapper(String element, Class mapper) {
158: if (mapper.isAssignableFrom(Mapper.class)) {
159: throw new IllegalArgumentException(mapper
160: + " is not a subclass of " + Mapper.class);
161: }
162: return (Class) this .customMappers.put(element, mapper);
163: }
164:
165: public Node getAttribute(Node aNode, String aNodeName) {
166: NamedNodeMap theAttributes = aNode.getAttributes();
167: return theAttributes.getNamedItem(aNodeName);
168: }
169:
170: public Mapper getMapper(String aNodeName) {
171: Mapper result = null;
172: Class mapperClass = (Class) this .customMappers.get(aNodeName);
173: if (mapperClass == null) {
174: mapperClass = (Class) DEFAULT_MAPPERS.get(aNodeName);
175: }
176:
177: if (mapperClass != null) {
178: try {
179: result = (Mapper) mapperClass.newInstance();
180: } catch (Exception e) {
181: throw new RuntimeException(
182: "Error instantiating mapper for " + aNodeName,
183: e);
184: }
185: } else {
186: SwingMLLogger.getInstance().log(SwingMLLogger.ERROR,
187: "No mapper found for " + aNodeName);
188: }
189: return result;
190: }
191:
192: public void iterate(Node aNode, Object aModel,
193: Container parentContainer) {
194: Mapper theMapper = null;
195: int theNodeType = 0;
196: NodeList theNodes = aNode.getChildNodes();
197: for (int i = 0; i < theNodes.getLength(); i++) {
198: aNode = theNodes.item(i);
199: theNodeType = aNode.getNodeType();
200: if (theNodeType == Node.ELEMENT_NODE) {
201: theMapper = this .getMapper(aNode.getNodeName());
202: if (theMapper != null) {
203: theMapper.mapModel(aNode, aModel, parentContainer);
204: }
205: }
206: }
207: }
208:
209: public void mapCommonAttributes(SwingMLModel aModel, Node aNode) {
210: Node theResultNode = null;
211:
212: theResultNode = this .getAttribute(aNode, Constants.ID);
213: if (theResultNode != null) {
214: aModel.setId(theResultNode.getNodeValue());
215: }
216:
217: theResultNode = this .getAttribute(aNode, Constants.NAME);
218: if (theResultNode != null) {
219: aModel.setName(theResultNode.getNodeValue());
220: }
221:
222: theResultNode = this .getAttribute(aNode, Constants.TEXT);
223: if (theResultNode != null) {
224: aModel.setText(theResultNode.getNodeValue());
225: }
226:
227: theResultNode = this .getAttribute(aNode, Constants.ORIENTATION);
228: if (theResultNode != null) {
229: aModel.setOrientation(theResultNode.getNodeValue());
230: }
231:
232: theResultNode = this .getAttribute(aNode, Constants.TOOLTIP);
233: if (theResultNode != null) {
234: aModel.setTooltip(theResultNode.getNodeValue());
235: }
236:
237: theResultNode = this .getAttribute(aNode, Constants.ICON);
238: if (theResultNode != null) {
239: URL url = URLHandler.handle(theResultNode.getNodeValue());
240: aModel.setIcon(url.toString());
241: }
242:
243: theResultNode = this .getAttribute(aNode, Constants.LAYOUT);
244: if (theResultNode != null) {
245: aModel.setLayout(theResultNode.getNodeValue());
246: } else {
247: aModel.setLayout("");
248: }
249:
250: theResultNode = getAttribute(aNode, Constants.FOREGROUND);
251: if (theResultNode != null) {
252: aModel.setForeground(ColorComponent
253: .getColorByName(theResultNode.getNodeValue()));
254: }
255:
256: theResultNode = getAttribute(aNode, Constants.BACKGROUND);
257: if (theResultNode != null) {
258: aModel.setBackground(ColorComponent
259: .getColorByName(theResultNode.getNodeValue()));
260: }
261:
262: theResultNode = getAttribute(aNode, Constants.FONT_STYLE);
263: if (theResultNode != null) {
264: aModel.setFontStyle(theResultNode.getNodeValue());
265: }
266: }
267:
268: public Document parse(String aSpec) {
269: try {
270: InputStream theXmlInputStream = new ByteArrayInputStream(
271: aSpec.getBytes());
272: InputSource theXmlSourceStream = new InputSource(
273: theXmlInputStream);
274: // Some of Microsoft's "smart punctuation" marks got into the data from users
275: // copying and pasting. Set the encoding below to handle those and not cause
276: // an Exception to be thrown during the parsing.
277: theXmlSourceStream.setEncoding("ISO-8859-1");
278: URL theCodeBase = SwingMLRenderer.getRenderer()
279: .getCodeBase();
280: if (theCodeBase != null) {
281: theXmlSourceStream.setSystemId(theCodeBase.toString());
282: }
283: DocumentBuilderFactory theFactory = DocumentBuilderFactory
284: .newInstance();
285: theFactory.setValidating(false);
286: DocumentBuilder theBuilder = theFactory
287: .newDocumentBuilder();
288: theBuilder.setErrorHandler(new org.xml.sax.ErrorHandler() {
289:
290: // validation errors
291: public void error(SAXParseException e) {
292: // TODO - Need to log these parsing errors somewhere (to a separate log?)
293: // Let Mark Fricke handle this when working on Error Uploading project }
294: }
295:
296: // fatal errors
297: public void fatalError(SAXParseException exception) {
298: // TODO - Need to log these parsing errors somewhere (to a separate log?)
299: // Let Mark Fricke handle this when working on Error Uploading project
300: }
301:
302: // warnings
303: public void warning(SAXParseException err) {
304: // TODO - Need to log these parsing errors somewhere (to a separate log?)
305: // Let Mark Fricke handle this when working on Error Uploading project
306: }
307: });
308:
309: Document theDocument = theBuilder.parse(theXmlSourceStream);
310: return theDocument;
311: } catch (FactoryConfigurationError e) {
312: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
313: } catch (ParserConfigurationException e) {
314: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
315: } catch (SAXException e) {
316: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
317: } catch (IOException e) {
318: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
319: }
320: return null;
321: }
322:
323: public Class removeRenderer(String element) {
324: return (Class) this.customMappers.remove(element);
325: }
326:
327: }
|