001: /*
002: * $Id: JGraphpadCodecAction.java,v 1.5 2005/08/07 14:24:57 gaudenz Exp $
003: * Copyright (c) 2001-2005, Gaudenz Alder
004: *
005: * All rights reserved.
006: *
007: * See LICENSE file for license details. If you are unable to locate
008: * this file please contact info (at) jgraph (dot) com.
009: */
010: package com.jgraph.codecplugin;
011:
012: import java.awt.Component;
013: import java.awt.event.ActionEvent;
014: import java.awt.geom.Rectangle2D;
015: import java.io.File;
016: import java.io.InputStream;
017: import java.io.OutputStream;
018: import java.io.PrintWriter;
019: import java.net.URL;
020:
021: import org.jgraph.JGraph;
022: import org.jgraph.graph.CellView;
023: import org.jgraph.graph.DefaultGraphModel;
024: import org.jgraph.graph.GraphLayoutCache;
025:
026: import com.jgraph.JGraphEditor;
027: import com.jgraph.JGraphpad;
028: import com.jgraph.editor.JGraphEditorAction;
029: import com.jgraph.editor.factory.JGraphEditorDiagramPane;
030: import com.jgraph.pad.action.JGraphpadFileAction;
031: import com.jgraph.pad.graph.JGraphpadBusinessObject;
032:
033: /**
034: * Export actions for HTML image maps, gxl and graphviz.
035: */
036: public class JGraphpadCodecAction extends JGraphpadFileAction {
037:
038: /**
039: * Specifies the name for the <code>saveImageMap</code> action.
040: */
041: public static final String NAME_SAVEIMAGEMAP = "saveImageMap";
042:
043: /**
044: * Specifies the name for the <code>saveGXL</code> action.
045: */
046: public static final String NAME_SAVEGXL = "saveGXL";
047:
048: /**
049: * Specifies the name for the <code>importGXL</code> action.
050: */
051: public static final String NAME_IMPORTGXL = "importGXL";
052:
053: /**
054: * Specifies the name for the <code>saveGraphviz</code> action.
055: */
056: public static final String NAME_SAVEGRAPHVIZ = "saveGraphviz";
057:
058: /**
059: * Constructs a new export action for the specified name.
060: */
061: protected JGraphpadCodecAction(String name, JGraphEditor editor) {
062: super (name, editor);
063: }
064:
065: /**
066: * Executes the action based on the action name.
067: *
068: * @param event
069: * The object that describes the event.
070: */
071: public void actionPerformed(ActionEvent event) {
072: Component component = getPermanentFocusOwner();
073: try {
074: if (component instanceof JGraph) {
075: JGraph graph = (JGraph) component;
076: if (getName().equals(NAME_SAVEIMAGEMAP))
077: doSaveImageMap(graph, dlgs.imageFileDialog(
078: getPermanentFocusOwnerOrParent(),
079: getString("SaveImage"), false,
080: lastDirectory), 0);
081: else if (getName().equals(NAME_SAVEGRAPHVIZ))
082: doSave(dlgs.fileDialog(
083: getPermanentFocusOwnerOrParent(),
084: getString("SaveGraphvizFile"), false,
085: ".dot",
086: getString("GraphvizFileDescription"),
087: lastDirectory), JGraphpadGraphvizCodec
088: .encode(
089: graph,
090: (graph.isSelectionEmpty()) ? graph
091: .getRoots() : graph
092: .getSelectionCells())
093: .getBytes());
094: else if (getName().equals(NAME_SAVEGXL))
095: doSave(dlgs.fileDialog(
096: getPermanentFocusOwnerOrParent(),
097: getString("SaveGXLFile"), false, ".xml",
098: getString("GXLFileDescription"),
099: lastDirectory), JGraphpadGXLCodec.encode(
100: graph,
101: (graph.isSelectionEmpty()) ? graph
102: .getRoots() : graph
103: .getSelectionCells()).getBytes());
104: else if (getName().equals(NAME_IMPORTGXL))
105: doImportGXL(graph.getGraphLayoutCache(), dlgs
106: .fileDialog(
107: getPermanentFocusOwnerOrParent(),
108: getString("OpenGXLFile"), true,
109: ".xml",
110: getString("GXLFileDescription"),
111: lastDirectory));
112: }
113: } catch (Exception e) {
114: dlgs.errorDialog(getPermanentFocusOwner(), e
115: .getLocalizedMessage());
116: }
117: }
118:
119: /**
120: * Imports the specified GXL file into the specified graph.
121: *
122: * @param cache
123: * The graph layout cache to import into.
124: * @param filename
125: * The filename to import from.
126: * @throws Exception
127: */
128: protected void doImportGXL(GraphLayoutCache cache, String filename)
129: throws Exception {
130: if (filename != null) {
131: InputStream in = editor.getModel().getInputStream(filename);
132: Object vertexPrototype = getValue(KEY_VERTEXPROTOTYPE);
133: Object edgePrototype = getValue(KEY_EDGEPROTOTYPE);
134: JGraphpadGXLCodec.decode(in, cache, vertexPrototype,
135: edgePrototype);
136: in.close();
137: lastDirectory = new File(filename).getParentFile();
138: }
139: }
140:
141: /**
142: * Exports the specified graph as an image map. The filename and map name
143: * are constructed out of the specified image filename.
144: *
145: * @param graph
146: * The graph to be exported as an image map.
147: * @param filename
148: * The filename of the image to export.
149: * @param inset
150: * The inset to apply to the image and coordinates.
151: */
152: protected void doSaveImageMap(JGraph graph, String filename,
153: int inset) throws Exception {
154: super .doSaveImage(JGraphEditorDiagramPane
155: .getParentDiagramPane(graph), inset, filename);
156: String basename = filename.substring(0, filename
157: .lastIndexOf("."));
158: String htmlFile = basename + ".html";
159: if (htmlFile != null) {
160: OutputStream out = editor.getModel().getOutputStream(
161: htmlFile);
162: String mapName = new File(basename).getName();
163: out.write(new String("<IMG SRC=\""
164: + JGraphEditor.toURL(new File(filename))
165: + "\" BORDER=\"0\" ISMAP USEMAP=\"#" + mapName
166: + "\">").getBytes());
167: writeMap(graph, mapName, inset, out);
168: out.flush();
169: out.close();
170: if (JGraphEditor.isURL(filename)) {
171: URL url = new URL(filename);
172: post(url, url.getFile(), MIME_HTML, out);
173: } else
174: lastDirectory = new File(filename).getParentFile();
175: }
176: }
177:
178: /**
179: * Writes a HTML image map to the specified stream applying inset to the
180: * coordinates of all cells. To find the URL and alt tag value of each cell,
181: * the {@link #getURL(JGraph, Object)} and {@link #getAlt(JGraph, Object)}
182: * methods are used respectively.
183: *
184: * @param graph
185: * The graph to create the image map for.
186: * @param mapName
187: * The name of the image map in the HTML code.
188: * @return Returns the number of entries in the map.
189: */
190: protected int writeMap(JGraph graph, String mapName, int inset,
191: OutputStream out) {
192: PrintWriter writer = new PrintWriter(out);
193: int written = 0;
194: if (graph.getModel().getRootCount() > 0) {
195: writer.println("<MAP NAME=\"" + mapName + "\">");
196: Rectangle2D bounds = graph.getCellBounds(graph.getRoots());
197: Object[] vertices = DefaultGraphModel.getAll(graph
198: .getModel());
199: for (int i = 0; i < vertices.length; i++) {
200: String alt = getAlt(graph, vertices[i]);
201: String href = getURL(graph, vertices[i]);
202: CellView view = graph.getGraphLayoutCache().getMapping(
203: vertices[i], false);
204: if (view != null && href != null && href.length() > 0) {
205: written++;
206: Rectangle2D b = (Rectangle2D) graph
207: .toScreen((Rectangle2D) ((Rectangle2D) view
208: .getBounds()).clone());
209: b.setFrame(b.getX() - bounds.getX() + inset, b
210: .getY()
211: - bounds.getY() + inset, b.getWidth(), b
212: .getHeight());
213: String rect = (int) b.getX() + "," + (int) b.getY()
214: + "," + (int) (b.getX() + b.getWidth())
215: + "," + (int) (b.getY() + b.getHeight());
216: String shape = "RECT";
217: writer.println("<AREA SHAPE=" + shape
218: + " COORDS=\"" + rect + "\" HREF=\"" + href
219: + "\" ALT=\"" + alt + "\">");
220: }
221: }
222: writer.println("</MAP>");
223: writer.flush();
224: writer.close();
225: }
226: return written;
227: }
228:
229: /**
230: * Returns the URL to be used in the image map of <code>graph</code> for
231: * the specified cell.
232: *
233: * @param graph
234: * The graph for which the image map is being created for.
235: * @param cell
236: * The cell to return the URL for.
237: * @return Returns a URL for <code>cell</code>.
238: */
239: protected String getURL(JGraph graph, Object cell) {
240: String url = getAlt(graph, cell);
241: if (JGraphEditor.isURL(url))
242: return url;
243: Object value = graph.getModel().getValue(cell);
244: if (JGraphEditor.isURL(value))
245: return String.valueOf(value);
246: if (value instanceof JGraphpadBusinessObject) {
247: JGraphpadBusinessObject obj = (JGraphpadBusinessObject) value;
248: Object property = obj.getProperty("url");
249: if (JGraphEditor.isURL(property))
250: return String.valueOf(property);
251: }
252: return "";
253: }
254:
255: /**
256: * Returns the value for the alt tag to be used in the image map of
257: * <code>graph</code> for the specified cell.
258: *
259: * @param graph
260: * The graph for which the image map is being created for.
261: * @param cell
262: * The cell to return the value of the alt tag for.
263: * @return Returns a alt tag for <code>cell</code>.
264: */
265: protected String getAlt(JGraph graph, Object cell) {
266: return graph.convertValueToString(cell);
267: }
268:
269: /**
270: * Bundle of all actions in this class.
271: */
272: public static class AllActions implements Bundle {
273:
274: /**
275: * Holds the actions. All actions require an editor reference and are
276: * therefore created at construction time.
277: */
278: public JGraphEditorAction actionSaveImageMap,
279: actionSaveGraphViz, actionSaveGXL, actionImportGXL;
280:
281: /**
282: * Constructs the action bundle for the enclosing class.
283: */
284: public AllActions(JGraphEditor editor) {
285: actionSaveImageMap = new JGraphpadCodecAction(
286: NAME_SAVEIMAGEMAP, editor);
287: actionSaveGraphViz = new JGraphpadCodecAction(
288: NAME_SAVEGRAPHVIZ, editor);
289: actionSaveGXL = new JGraphpadCodecAction(NAME_SAVEGXL,
290: editor);
291: actionImportGXL = new JGraphpadCodecAction(NAME_IMPORTGXL,
292: editor);
293: Object vertexPrototype = editor.getSettings().getObject(
294: JGraphpad.KEY_VERTEXPROTOTYPE);
295: Object edgePrototype = editor.getSettings().getObject(
296: JGraphpad.KEY_EDGEPROTOTYPE);
297: actionImportGXL.putValue(KEY_VERTEXPROTOTYPE,
298: vertexPrototype);
299: actionImportGXL.putValue(KEY_EDGEPROTOTYPE, edgePrototype);
300: }
301:
302: /*
303: * (non-Javadoc)
304: */
305: public JGraphEditorAction[] getActions() {
306: return new JGraphEditorAction[] { actionSaveImageMap,
307: actionSaveGraphViz, actionSaveGXL, actionImportGXL };
308: }
309:
310: /*
311: * (non-Javadoc)
312: */
313: public void update() {
314: Component component = getPermanentFocusOwner();
315: boolean e = component instanceof JGraph;
316: actionSaveImageMap.setEnabled(e);
317: actionSaveGraphViz.setEnabled(e);
318: actionSaveGXL.setEnabled(e);
319: actionImportGXL.setEnabled(e);
320: }
321: }
322:
323: }
|