/**
* Copyright 1999-2009 The Pegadi Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pegadi.storysketch;
import org.jgraph.graph.*;
import org.pegadi.storysketch.cells.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.text.DateFormat;
import java.util.*;
public abstract class XMLUtil {
private static final Logger log = LoggerFactory.getLogger(XMLUtil.class);
public static Element createModelElement(GraphModel model, Document doc) {
Element element = doc.createElement("model");
Hashtable hash = new Hashtable();
for(int i = 0; i < model.getRootCount(); i++) {
Object cell = model.getRootAt(i);
if(cell instanceof StorySketchCell) {
StorySketchCell sCell = (StorySketchCell)cell;
Element e = sCell.getCellElement(doc);
// Add the <attributes> element
e.appendChild(XMLUtil.getAttributesElement(sCell, doc));
e.setAttribute("id",Integer.toString(hash.size()));
e.setAttribute("created", DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.ENGLISH).format(sCell.getCreatedDate()));
hash.put(cell, hash.size());
for(int p = 0; p < model.getChildCount(cell); p++) {
if(model.getChild(cell, p) instanceof Port) {
Port port = (Port) model.getChild(cell, p);
Element portElement = doc.createElement("port");
portElement.setAttribute("id",Integer.toString(hash.size()));
hash.put(port, hash.size());
portElement.appendChild(getAttributesElement(port, doc));
e.appendChild(portElement);
}
}
element.appendChild(e);
}
}
// Add edges
for(int i = 0; i < model.getRootCount(); i++) {
Object cell = model.getRootAt(i);
if (cell instanceof Edge) {
Edge edge = (Edge) cell;
Element edgeElement = doc.createElement("edge");
Object sourceObject = edge.getSource();
Object targetObject = edge.getTarget();
Integer source = null;
if(sourceObject != null)
source = (Integer) hash.get(sourceObject);
Integer target = null;
if(targetObject != null)
target = (Integer) hash.get(targetObject);
if(source != null) {
edgeElement.setAttribute("source", source.toString());
}
if(target != null) {
edgeElement.setAttribute("target", target.toString());
}
edgeElement.setAttribute("label", edge.toString());
//edgeElement.appendChild(getAttributesElement(edge, doc));
element.appendChild(edgeElement);
}
}
return element;
}
public static Element getAttributesElement(GraphCell cell, Document doc) {
Element attributes = doc.createElement("attributes");
Map map = cell.getAttributes();
Set keys = map.keySet();
for (Object key1 : keys) {
Element attribute = doc.createElement("attribute");
Object key = key1;
Object value = map.get(key);
String valueString = value.toString();
if (key == GraphConstants.BOUNDS) {
Rectangle bounds = GraphConstants.getBounds(map);
valueString = bounds.x + "," + bounds.y + "," + bounds.width + "," + bounds.height;
}
attribute.setAttribute("key", key.toString());
attribute.setAttribute("value", valueString);
attributes.appendChild(attribute);
}
return attributes;
}
public static Map getAttributes(Element e) {
Map map = GraphConstants.createMap();
NodeList nl = e.getElementsByTagName("attribute");
for(int i = 0; i < nl.getLength(); i++) {
Element attribute = (Element)nl.item(i);
String key = attribute.getAttribute("key");
String value = attribute.getAttribute("value");
if(key.equals(GraphConstants.BOUNDS)) {
StringTokenizer st = new StringTokenizer(value,",");
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
int h = Integer.parseInt(st.nextToken());
Rectangle bounds = new Rectangle(x,y,w,h);
GraphConstants.setBounds(map,bounds);
}
}
return map;
}
public static GraphModel getGraphModel(Element e) {
StorySketchGraphModel model = new StorySketchGraphModel();
NodeList modelElements = e.getElementsByTagName("model");
if(modelElements.getLength() != 1) {
return model;
}
Element modelElement = (Element)modelElements.item(0);
NodeList nl = modelElement.getChildNodes();
ArrayList cells = new ArrayList();
Hashtable ids = new Hashtable();
Hashtable attributes = new Hashtable();
ConnectionSet cs = new ConnectionSet();
for(int i = 0; i < nl.getLength(); i++) {
if(nl.item(i) instanceof Element) {
Element element = (Element) nl.item(i);
StorySketchCell cell = null;
if(element.getNodeName().equals("personcell")) {
cell = new PersonCell();
} else if(element.getNodeName().equals("archivecell")) {
cell = new ArchiveCell();
} else if(element.getNodeName().equals("appointmentcell")) {
cell = new AppointmentCell();
} else if(element.getNodeName().equals("conflictcell")) {
cell = new ConflictCell();
} else if(element.getNodeName().equals("notecell")) {
cell = new NoteCell();
} else if(element.getNodeName().equals("quotecell")) {
cell = new QuoteCell();
}
if(cell != null) {
cell.setCellElement(element);
Map a = getAttributes((Element)element.getElementsByTagName("attributes").item(0));
attributes.put(cell, a);
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.ENGLISH);
try {
String date = element.getAttribute("created");
if (date != null && !date.equals("")) {
cell.setCreatedDate(df.parse(date));
} else {
cell.setCreatedDate(new Date());
}
} catch (Exception ex) {
log.error("Woops. Could not parse date. This should not happen (but of course it will)", ex);
}
ids.put(element.getAttribute("id"), cell);
cells.add(cell);
NodeList ports = element.getElementsByTagName("port");
for(int p = 0; p < ports.getLength(); p++) {
Element portElement = (Element) ports.item(p);
String id = portElement.getAttribute("id");
Map map = getAttributes(portElement);
DefaultPort dp = new DefaultPort();
ids.put(id,dp);
attributes.put(dp,map);
cells.add(dp);
cell.add(dp);
}
}
}
}
for(int i = 0; i < nl.getLength(); i++) {
if(nl.item(i) instanceof Element) {
Element element = (Element) nl.item(i);
if(element.getNodeName().equals("edge")) {
String source = element.getAttribute("source");
String target = element.getAttribute("target");
String label = element.getAttribute("label");
DefaultEdge edge = new DefaultEdge(label);
Port sourcePort = null;
Port targetPort = null;
if(source != null) {
sourcePort = (Port) ids.get(source);
}
if(target != null) {
targetPort = (Port) ids.get(target);
}
cs.connect(edge, sourcePort, true);
cs.connect(edge, targetPort, false);
//edge.setSource(sourcePort);
//edge.setTarget(targetPort);
Map map = GraphConstants.createMap();
GraphConstants.setRouting(map, GraphConstants.ROUTING_SIMPLE);
GraphConstants.setLineStyle(map, GraphConstants.STYLE_BEZIER);
attributes.put(edge,map);
cells.add(edge);
}
}
}
model.insert(cells.toArray(),
attributes,
cs,
null,
null);
return model;
}
public static String extractValue(Element e, String name) {
NodeList nl = e.getElementsByTagName(name);
StringBuffer value = new StringBuffer();
if(nl.getLength() > 0) {
NodeList children = nl.item(0).getChildNodes();
for(int i = 0; i < children.getLength(); i++) {
if(children.item(i) instanceof Text) {
value.append(((Text) children.item(i)).getData());
}
}
return value.toString();
} else {
return "";
}
}
public static Element createParagraphElement(String name, String content, Document doc) {
Element element = doc.createElement(name);
BufferedReader br = new BufferedReader(new StringReader(content));
try {
while(br.ready()) {
// Create an element for this node
String p = br.readLine();
// To avoid an infinite loop
if(p==null)
break;
Element pe = doc.createElement("p");
//Add text to paragraph node
Text t = doc.createTextNode(p);
pe.appendChild(t);
element.appendChild(pe);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return element;
}
public static String getStringFromParagraphElement(Element element) {
StringBuffer value = new StringBuffer();
NodeList nl = element.getElementsByTagName("p");
for(int i = 0; i < nl.getLength(); i++) {
NodeList children = nl.item(i).getChildNodes();
for(int c = 0; c < children.getLength(); c++) {
if(children.item(c) instanceof Text) {
value.append(((Text) children.item(c)).getData());
}
}
if(i != nl.getLength() -1) {
value.append("\n");
}
}
return value.toString();
}
}