package er.directtoweb.pages; import java.io.File; import java.io.IOException; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WOResponse; import com.webobjects.eoaccess.EOEntity; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSData; import com.webobjects.foundation.NSMutableArray; import er.extensions.appserver.ERXApplication; import er.extensions.foundation.ERXFileUtilities; import er.extensions.foundation.ERXRuntimeUtilities; import er.extensions.foundation.ERXRuntimeUtilities.Result; import er.extensions.foundation.ERXRuntimeUtilities.TimeoutException; /** * Creates a GrahpViz page for those that needs such trivial tools. Call up with * the ERD2WDirectAction and use visibleEntityNames to restrict based on page * config name. * * @author ak * */ public class ERD2WGraphVizPage extends ERD2WPage { /** * Do I need to update serialVersionUID? * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a> */ private static final long serialVersionUID = 1L; /** interface for all the keys used in this pages code */ public interface Keys extends ERD2WPage.Keys { public static String format = "format"; } private int _nodeID = 0; public ERD2WGraphVizPage(WOContext context) { super(context); } public int nodeID() { return _nodeID ++; } public NSArray<String> attributes() { NSMutableArray<String> result = new NSMutableArray<>(); EOEntity entity = entity(); for (String key : (NSArray<String>)displayPropertyKeys()) { if(entity.classDescriptionForInstances().attributeKeys().containsObject(key) && entity.classPropertyNames().containsObject(key)) { result.addObject(key); } } return result; } public NSArray<String> toOneRelationships() { NSMutableArray<String> result = new NSMutableArray<>(); EOEntity entity = entity(); for (String key : (NSArray<String>)displayPropertyKeys()) { if(entity.classDescriptionForInstances().toOneRelationshipKeys().containsObject(key) && entity.classPropertyNames().containsObject(key)) { result.addObject(key); } } return result; } public String tag() { return "<" + propertyKey() + ">"; } public String nodeType() { return "->"; } public NSArray<String> toManyRelationships() { NSMutableArray<String> result = new NSMutableArray<>(); EOEntity entity = entity(); for (String key : (NSArray<String>)displayPropertyKeys()) { if(entity.classDescriptionForInstances().toManyRelationshipKeys().containsObject(key) && entity.classPropertyNames().containsObject(key)) { result.addObject(key); } } return result; } /* * Disable click to open */ public boolean clickToOpenEnabled(WOResponse response, WOContext context) { return false; } @Override public void appendToResponse(WOResponse response, WOContext context) { // we do NOT want to expose our model to just everyone... if (ERXApplication.isDevelopmentModeSafe()) { super.appendToResponse(response, context); } response.setHeader("text/plain", "content-type"); String format = (String) d2wContext().valueForKey(Keys.format); if (format == null) { format = context.request().stringFormValueForKey("format"); } if (format != null) { String dot = response.contentString(); File f = null; try { f = File.createTempFile("GVTemp", "dot"); ERXFileUtilities.stringToFile(dot, f); Result result = ERXRuntimeUtilities.execute(new String[] { "/usr/local/bin/dot", "-T" + format, "", f.getAbsolutePath() }, null, null, 0); response.setContent(new NSData(result.getResponse())); if (format.equals("svg")) { response.setHeader("image/svg+xml", "content-type"); } else if (format.equals("pdf")) { response.setHeader("application/pdf", "content-type"); } else { throw new IllegalArgumentException("Only handles 'pdf' and 'svg'"); } } catch (IOException ex) { log.error(ex, ex); } catch (TimeoutException ex) { log.error(ex, ex); } finally { if(f != null) { f.delete(); } } } } }