001package com.basilv.examples.dom4j; 002 003import java.io.File; 004 005import org.dom4j.*; 006import org.dom4j.io.SAXReader; 007 008public class MazeXmlConverter 009{ 010 private static final String MAZE_ELEMENT = "maze"; 011 private static final String HEIGHT_ATTRIBUTE = "height"; 012 private static final String WIDTH_ATTRIBUTE = "width"; 013 private static final String WALL_ELEMENT = "wall"; 014 private static final String START_X_ATTRIBUTE = "startX"; 015 private static final String START_Y_ATTRIBUTE = "startY"; 016 private static final String END_X_ATTRIBUTE = "endX"; 017 private static final String END_Y_ATTRIBUTE = "endY"; 018 019 public String toXml(Maze maze) { 020 Document document = DocumentHelper.createDocument(); 021 Element root = document.addElement(MAZE_ELEMENT) 022 .addAttribute(WIDTH_ATTRIBUTE, Integer.toString(maze.getSize().width)) 023 .addAttribute(HEIGHT_ATTRIBUTE, Integer.toString(maze.getSize().height)) 024 .addText(nullToEmpty(maze.getDescription())); 025 026 for (Wall wall : maze.getWalls()) { 027 root.addElement(WALL_ELEMENT) 028 .addAttribute(START_X_ATTRIBUTE, Integer.toString(wall.getStart().x)) 029 .addAttribute(START_Y_ATTRIBUTE, Integer.toString(wall.getStart().y)) 030 .addAttribute(END_X_ATTRIBUTE, Integer.toString(wall.getEnd().x)) 031 .addAttribute(END_Y_ATTRIBUTE, Integer.toString(wall.getEnd().y)); 032 } 033 034 return document.asXML(); 035 } 036 037 private String nullToEmpty(String text) { 038 if (text == null) { 039 return ""; 040 } else { 041 return text; 042 } 043 } 044 045 public Maze fromXml(File xmlFile) { 046 SAXReader reader = new SAXReader(); 047 try { 048 Document document = reader.read(xmlFile); 049 return fromXml(document); 050 } catch (DocumentException e) { 051 throw new RuntimeException("Error reading file [" + xmlFile.getAbsolutePath() + "].", e); 052 } 053 } 054 055 // For testing. 056 public Maze fromXml(String xml) { 057 try { 058 Document document = DocumentHelper.parseText(xml); 059 return fromXml(document); 060 } catch (DocumentException e) { 061 throw new RuntimeException("Error parsing xml string.", e); 062 } 063 } 064 065 private Maze fromXml(Document document) { 066 Element root = document.getRootElement(); 067 068 int width = getElementIntAttribute(root, WIDTH_ATTRIBUTE); 069 int height = getElementIntAttribute(root, HEIGHT_ATTRIBUTE); 070 071 Maze maze = new Maze(width, height); 072 maze.setDescription(root.getText()); 073 074 for (Object elementObj : root.elements(WALL_ELEMENT)) { 075 Element element = (Element) elementObj; 076 077 int startX = getElementIntAttribute(element, START_X_ATTRIBUTE); 078 int startY = getElementIntAttribute(element, START_Y_ATTRIBUTE); 079 int endX = getElementIntAttribute(element, END_X_ATTRIBUTE); 080 int endY = getElementIntAttribute(element, END_Y_ATTRIBUTE); 081 082 maze.addWall(startX, startY, endX, endY); 083 } 084 085 return maze; 086 } 087 088 private int getElementIntAttribute(Element element, String attributeName) { 089 Attribute attribute = getNonNullAttributeForElement(element, attributeName); 090 return Integer.parseInt(attribute.getValue()); 091 } 092 093 private Attribute getNonNullAttributeForElement(Element element, String attributeName) { 094 Attribute attribute = element.attribute(attributeName); 095 if (attribute == null) { 096 throw new RuntimeException("Element [" + element.getName() + "] missing attribute named [" + attributeName + "]."); 097 } 098 return attribute; 099 } 100 101}