package glg_demos; import java.io.*; import java.net.*; import javax.servlet.*; import javax.servlet.http.*; import javax.imageio.*; import java.awt.image.*; import com.genlogic.*; public final class GlgCircuitServlet extends HttpServlet implements GlgErrorHandler { static final long serialVersionUID = 0; // If true, the resource path is used to animate resources of the drawing. // If false, stored resource ID is used to set resource directly with // null path using the Extended API. // Alternatively, tags may be used instead of resources. // final boolean USE_RESOURCE_PATH = false; static GlgObject viewport = null; // Drawing path relative to the servlet app's dir. static String drawing_name = "/drawings/electric_circuit.g"; // Global simulated data used by all servlets. static GlgCircuitDemoData data = new GlgCircuitDemoData(); ///////////////////////////////////////////////////////////////// // A wrapper around the main method, doGet2(), to properly handle // the access synchronization and unlocking on an error. ///////////////////////////////////////////////////////////////// public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException { try { doGet2( request, response ); } catch( Exception e ) { // Unlock if was interrupted by the exception while locked. GlgObject.UnlockThread(); throw new ServletException( e ); // Re-thow to log an error } // Unlock just in case the code did not do it due to a programming error. GlgObject.UnlockThread(); } ///////////////////////////////////////////////////////////////// // Main servlet's method: everything is handled here. ///////////////////////////////////////////////////////////////// public void doGet2( HttpServletRequest request, HttpServletResponse response ) { InitGLG(); // Init the Toolkit // Load the drawing (if first time) and update with data. // Get requested width/height of the image. int width = GetIntegerParameter( request, "width", 800 ); int height = GetIntegerParameter( request, "height", 600 ); // Limit max. size to avoid running out of heap space creating an image. if( width > 1000 ) width = 1000; if( height > 1000 ) height = 1000; // This example reuses the same drawing between all servlets' threads. // Therefore lock to synchronize and prevent other servlets from // changing the drawing size, etc., before we are done. GlgObject.Lock(); // Load drawing just once and share it among all servlets and threads. // Alternatively, each servlet may load its own drawing. if( viewport == null ) // First time: load the drawing. { viewport = LoadDrawing( drawing_name ); viewport.SetImageSize( width, height ); viewport.SetupHierarchy(); // Setup to prepare to receive data // Create a list of resources to animate by querying them from the // drawing. GlgObject resource_list = GetResourceList( viewport, null, null ); if( resource_list == null ) Error( "Found no resources to animate." ); else data.resource_list = resource_list; } else // Already loaded, reuse the drawing. viewport.SetImageSize( width, height ); // Get the new data values from a custom data source. data.UpdateCircuitData(); UpdateDrawingWithData(); // Push new data into the drawing. // Setup after data update to prepare to generate image. viewport.SetupHierarchy(); // Create an image of the viewport's graphics. BufferedImage image = (BufferedImage) viewport.CreateImage( null ); GlgObject.Unlock(); // Write the image try { response.setContentType("image/png"); OutputStream out_stream = response.getOutputStream(); ImageIO.write( image, "png", out_stream ); out_stream.close(); } catch( IOException e ) { // Log( "Aborted writing of image file." ); } } ///////////////////////////////////////////////////////////////// // Helper methods ///////////////////////////////////////////////////////////////// int GetIntegerParameter( HttpServletRequest request, String name, int default_value ) { String parameter_string = request.getParameter( name ); if( parameter_string == null || parameter_string.equals( "" ) ) return default_value; try { return Integer.parseInt( parameter_string ); } catch( NumberFormatException e ) { Log( "Invalid parameter value for: " + name + " = " + parameter_string ); return default_value; } } ///////////////////////////////////////////////////////////////// void Log( String msg ) { getServletContext().log( "GlgCircuitServlet: " + msg ); } // GlgErrorHandler interface method for error handling. public void Error( String message ) { Log( message ); // Log errors Log( GlgObject.GetStackTraceAsString() ); // Print stack } ///////////////////////////////////////////////////////////////// void InitGLG() { // Set an error handler to log errors. GlgObject.SetErrorHandler( this ); GlgObject.Init(); // Init GlgToolkit } ///////////////////////////////////////////////////////////////// GlgObject LoadDrawing( String drawing_name ) { // Get drawing URL relative to the servlet's directory. URL drawing_url = null; try { drawing_url = getServletConfig().getServletContext().getResource( drawing_name ); } catch( MalformedURLException e ) { Log( "Malformed URL: " + drawing_name ); return null; } if( drawing_url == null ) { Log( "Can't find resource: " + drawing_name ); return null; } // Load drawing from the URL viewport = GlgObject.LoadWidget( drawing_url.toString(), GlgObject.URL ); if( viewport == null ) { Log( "Can't load drawing: " + drawing_name ); return null; } // Disable viewport border in the image: let html define it if needed. viewport.SetDResource( "LineWidth", 0. ); return viewport; } ////////////////////////////////////////////////////////////////////////// // Creates a list of resources to animate defined in the drawing. // Queries the drawing to include all resources of interest that are // marked by having "#" as the first character of their names. // Alternatively, tags may be used instead of resources. ////////////////////////////////////////////////////////////////////////// GlgObject GetResourceList( GlgObject obj, String res_path, GlgObject list ) { // Using only named resources in this example, no aliases. GlgObject res_list = obj.CreateResourceList( true, false, false ); if( res_list == null ) return list; int size = res_list.GetSize(); for( int i=0; i