add info page
authorymh <ymh.work@gmail.com>
Tue, 30 Mar 2010 17:53:36 +0200
changeset 7 41b17723d6c8
parent 6 3a1bcc02b5a6
child 8 9f3b0b3a56a4
child 9 6746733ca0ad
add info page
WebContent/WEB-INF/lib/freemarker.jar
WebContent/WEB-INF/lib/log4j-1.2.15.jar
WebContent/WEB-INF/log4j.properties
WebContent/WEB-INF/templates/info.ftl
WebContent/WEB-INF/web.xml
src/HelloResource.java
src/fr/iri/thd/sonyengine/web/FreemarkerViewProcessor.java
src/fr/iri/thd/sonyengine/web/InfoResource.java
src/fr/iri/thd/sonyengine/web/ServletContainer.java
Binary file WebContent/WEB-INF/lib/freemarker.jar has changed
Binary file WebContent/WEB-INF/lib/log4j-1.2.15.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebContent/WEB-INF/log4j.properties	Tue Mar 30 17:53:36 2010 +0200
@@ -0,0 +1,7 @@
+# This sets the global logging level and specifies the appenders
+log4j.rootLogger=INFO, consoleAppender
+
+# settings for the console appender
+log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
+log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
+log4j.appender.consoleAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebContent/WEB-INF/templates/info.ftl	Tue Mar 30 17:53:36 2010 +0200
@@ -0,0 +1,32 @@
+<html>
+<head>
+  <title>Info on </title>
+</head>
+<body>
+    <h1>Informations</h1>
+    <table>
+    <thead>
+    <tr>
+      <th>Text</th>
+      <th>Value</th>
+    </tr>
+    </thead>
+    <tr>
+      <td>DATABASE PATH</td>
+      <td>${dbpath}</td>
+    </tr>
+    <tr>
+      <td>Segments</td>
+      <td>${segments_nb}</td>
+    </tr>
+    <tr>
+      <td>Segments in db</td>
+      <td>${segments_db_nb}</td>
+    </tr>
+    <tr>
+      <td>Tags</td>
+      <td>${tags_nb}</td>
+    </tr>    
+    </table>
+</body>
+</html>
\ No newline at end of file
--- a/WebContent/WEB-INF/web.xml	Wed Mar 24 12:41:26 2010 +0100
+++ b/WebContent/WEB-INF/web.xml	Tue Mar 30 17:53:36 2010 +0200
@@ -15,8 +15,12 @@
         fr.iri.thd.sonyengine.web.ServletContainer
     </servlet-class>
     <init-param>
-      <param-name>initDatabasePath</param-name>
-      <param-value>c:/tmp/db</param-value>
+      <param-name>com.sun.jersey.config.property.packages</param-name>
+      <param-value>fr.iri.thd.sonyengine.web</param-value>
+    </init-param>
+    <init-param>
+      <param-name>log4j-properties-location</param-name>
+      <param-value>/WEB-INF/log4j.properties</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
   </servlet>
@@ -24,4 +28,10 @@
     <servlet-name>sonyengine</servlet-name>
     <url-pattern>/*</url-pattern>
   </servlet-mapping>
+  <!--context-param>
+    <param-name>initDatabasePath</param-name>
+    <param-value>BAR</param-value>
+  </context-param-->
+  <!--  or in context.xml  -->
+  <!--Parameter name="initDatabasePath" value="FOOBAR" /-->
 </web-app>
\ No newline at end of file
--- a/src/HelloResource.java	Wed Mar 24 12:41:26 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-
-@Path ("helloworld")
-public class HelloResource {
-
-	@GET
-	@Produces ("text/plain")
-	public String sayHello() {
-		return "Hello World";
-		}	
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fr/iri/thd/sonyengine/web/FreemarkerViewProcessor.java	Tue Mar 30 17:53:36 2010 +0200
@@ -0,0 +1,266 @@
+package fr.iri.thd.sonyengine.web;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.log4j.Logger;
+
+import com.sun.jersey.api.view.Viewable;
+import com.sun.jersey.spi.template.ViewProcessor;
+
+import freemarker.cache.WebappTemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+
+/**
+* Match a Viewable-named view with a Freemarker template.
+*
+* <p>You can configure the location of your templates with the
+* context param 'freemarker.template.path'. If not assigned
+* we'll use a default of <tt>WEB-INF/templates</tt>. Note that this uses
+* Freemarker's {@link freemarker.cache.WebappTemplateLoader} to
+* load/cache the templates, so check its docs (or crank up the logging
+* under the 'freemarker.cache' package) if your templates
+* aren't getting loaded.</p>
+*
+* <p>This will put your Viewable's model object in the template
+* variable "it", unless the model is a Map. If so, the values
+* will be assigned to the template assuming the map is of
+* type <tt>Map&lt;String,Object></tt>.</p>
+*
+* Example of configuring the template path:
+*
+* <pre>
+* &lt;web-app ...
+* &lt;display-name>Awesomeo 2000&lt;/display-name>
+* &lt;context-param>
+* &lt;param-name>freemarker.template.path&lt;/param-name>
+* &lt;param-value>/WEB-INF/views&lt;/param-value>
+* &lt;/context-param>
+* ...
+*</pre>
+*
+* <p>You'll also need to tell Jersey the package where this provider
+* is stored. Typically this is through the servlet's init params -- for instance,
+* in the below configuration we could store this in <tt>com.myco.jersey</tt> and
+* my resources in <tt>com.myco.jersey.resource</tt></p>
+*
+* <pre>
+* &lt;servlet>
+* &lt;servlet-name>My REST App&lt;/servlet-name>
+* &lt;servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer&lt;/servlet-class>
+* &lt;init-param>
+* &lt;param-name>com.sun.jersey.config.property.packages&lt;/param-name>
+* &lt;param-value>com.myco.jersey;com.myco.jersey.resource&lt;/param-value>
+* &lt;/init-param>
+* &lt;/servlet>
+* </pre>
+*
+* <p>There are a number of methods you can override to change the behavior, such as
+* handling processing exceptions, changing the default template extension, or
+* adding variables to be assigned to every template context.
+*
+* @author Chris Winters <chris@cwinters.com>
+* @version $Revision: #5 $ (Last update: $DateTime: 2009/04/03 20:12:26 $ $Author: cwinters $)
+*/
+@Provider
+public class FreemarkerViewProcessor implements ViewProcessor<Template> {
+	
+    private static final Logger log = Logger.getLogger( FreemarkerViewProcessor.class );
+	 
+    private static Configuration freemarkerConfig;
+ 
+    private String rootPath;
+    private ServletContext servletContext;
+    
+    public FreemarkerViewProcessor() {
+    }
+
+    /**
+	* @return extension for templates, ".ftl" by default; if we don't see this at the
+	* end of your view we'll append it so we can find the template resource
+	*/
+	protected String getDefaultExtension() {
+	        return ".ftl";
+	}
+	
+    /**
+	* Define additional variables to make available to the template.
+	* @param viewableVariables variables provided by whomever generated the viewable object;
+	* these are provided for reference only, there will be no effect if you modify this map
+	* @return new variables for the template context, which will override any defaults provided
+	*/
+    protected Map<String,Object> getVariablesForTemplate(
+            final Map<String,Object> viewableVariables )
+    {
+        return new HashMap<String,Object>();
+    }
+    
+    /**
+	* Catch any exception generated during template processing.
+	*
+	* @param t throwable caught
+	* @param templatePath path of template we're executing
+	* @param templateContext context use when evaluating this template
+	* @param out output stream from servlet container
+	* @throws IOException on any write errors, or if you want to rethrow
+	*/
+    protected void onProcessException( final Throwable t, final Template template,
+                                       final Map<String,Object> templateContext,
+                                       final OutputStream out )
+            throws IOException
+    {
+        log.error( "Error processing freemarker template @ " + template.getName() + ": " + t.getMessage(), t );
+        out.write( "<pre>".getBytes() );
+        t.printStackTrace( new PrintStream( out ) );
+        out.write( "</pre>".getBytes() );
+    }
+	    
+    /**
+	* Modify freemarker configuration after we've created it and applied any
+	* settings from 'freemarker.properties' on the classpath.
+	*
+	* @param config configuration we've created so far
+	* @param context servlet context used to create the configuration
+	*/
+	protected void assignFreemarkerConfig( final Configuration config,
+                                           final ServletContext context )
+    {
+        // don't always put a ',' in numbers (e.g., id=2000 vs id=2,000)
+        config.setNumberFormat( "0" );
+ 
+        // don't look for list.en.ftl when list.ftl requested
+        config.setLocalizedLookup( false );
+ 
+        // don't cache
+        config.setTemplateUpdateDelay(0);
+ 
+        log.info( "OK: Assigned default freemarker configuration" );
+ 
+    }
+	    
+    @Context
+    public void setServletContext( final ServletContext context )
+    {
+        this.servletContext = context;
+ 
+        freemarkerConfig = new Configuration();
+ 
+        rootPath = context.getInitParameter( "freemarker.template.path" );
+        if ( rootPath == null || rootPath.trim().length() == 0 ) {
+            log.info( "No 'freemarker.template.path' context-param, " +
+                      "defaulting to '/WEB-INF/templates'" );
+            rootPath = "/WEB-INF/templates";
+        }
+        rootPath = rootPath.replaceAll( "/$", "" );
+ 
+        freemarkerConfig.setTemplateLoader( new WebappTemplateLoader( context, rootPath ) );
+ 
+        final InputStream fmProps = context.getResourceAsStream( "freemarker.properties" );
+        if ( fmProps != null ) {
+            try {
+                freemarkerConfig.setSettings( fmProps );
+                log.info( "OK: Assigned freemarker configuration from 'freemarker.properties'" );
+                return;
+            }
+            catch ( Throwable t ) {
+                log.warn( "Failed to load/assign freemarker.properties, will use default settings " +
+                          "instead; error: " + t.getMessage() );
+            }
+        }
+        assignFreemarkerConfig( freemarkerConfig, context );
+    }
+    
+	@Override
+	public Template resolve(String path) {
+
+		String resolvedPath = null;
+		
+		if ( log.isDebugEnabled() )
+            log.debug( "Resolving freemarker template path (" + path + ")" );
+ 
+        // accept both '/path/to/template' and '/path/to/template.ftl'
+        final String defaultExtension = getDefaultExtension();
+        final String filePath = path.endsWith( defaultExtension ) ? path : path + defaultExtension;
+        try {
+            final String fullPath = rootPath + filePath;
+            final boolean templateFound = servletContext.getResource( fullPath ) != null;
+            if ( ! templateFound )
+                log.warn( "Template not found [Given path: " + path + "] " +
+                          "[Servlet context path: " + fullPath + "]" );
+            resolvedPath =  templateFound ? filePath : null;
+        }
+        catch ( MalformedURLException e ) {
+            log.warn( "Caught MalformedURLException when trying to get freemarker resource (" + filePath + ") " +
+                      "from the servlet context: " + e.getMessage() );
+            resolvedPath = null;
+        }
+        
+        if(resolvedPath != null) {
+        	final Template template;
+	        if ( log.isDebugEnabled() )
+	            log.debug( "Evaluating freemarker template (" + resolvedPath + ")");
+	        try {
+				template = freemarkerConfig.getTemplate( resolvedPath );
+			} catch (IOException e) {
+				log.warn( "Caught IOException when trying to get freemarker resource (" + filePath + ") " +
+	                      "from the servlet context: " + e.getMessage() );
+				return null;
+			}
+	        if ( log.isDebugEnabled() )
+	            log.debug( "OK: Resolved freemarker template" );
+	        return template;
+	        
+        }
+        else
+        	return null;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void writeTo(final Template template, final Viewable viewable, final OutputStream out)
+			throws IOException {
+		
+        out.flush(); // send status + headers
+   	  
+        final Map<String,Object> vars = new HashMap<String, Object>();
+ 
+        final Object model = viewable.getModel();
+        if ( model instanceof Map<?, ?> ) {
+            vars.putAll( (Map<String, Object>) model );
+        }
+        else {
+            vars.put( "it", model );
+        }
+ 
+        final Map<String,Object> extraVars = getVariablesForTemplate( new HashMap<String, Object>( vars ) );
+        if ( extraVars != null ) {
+            vars.putAll( extraVars );
+        }
+        
+        final OutputStreamWriter writer = new OutputStreamWriter( out );
+ 
+        try {
+            template.process( vars, writer );
+            if ( log.isDebugEnabled() )
+                log.debug( "OK: Processed freemarker template" );
+        }
+        catch ( Throwable t ) {
+            onProcessException( t, template, vars, out );
+        }
+
+	}
+	
+	
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fr/iri/thd/sonyengine/web/InfoResource.java	Tue Mar 30 17:53:36 2010 +0200
@@ -0,0 +1,49 @@
+package fr.iri.thd.sonyengine.web;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+import thd.ThdEngine;
+
+import com.sun.jersey.api.view.Viewable;
+
+import fr.iri.thd.sonyengine.core.DataAccessor;
+import fr.iri.thd.sonyengine.core.DbEnv;
+
+@Path("info")
+public class InfoResource {
+
+	@GET
+	@Produces(MediaType.TEXT_HTML)
+	public Viewable info(@Context ServletContext context) {
+		String dbpath = (String)context.getAttribute(ServletContainer.DB_PATH_ATTRIBUTE);
+		
+		final int segments_nb = ThdEngine.getEngine().getAllMovieFragments().size();
+		
+		final DbEnv dbenv = (DbEnv)context.getAttribute(ServletContainer.DB_ENV_ATTRIBUTE);		
+		final DataAccessor da = new DataAccessor(dbenv.getEntityStore());
+		final long segments_db_nb = da.movieFragmentById.count();
+		final long tags_nb = da.tagById.count();
+		
+		
+		final Map<String,Object> vars = new HashMap<String, Object>();
+		
+		vars.put("dbpath", dbpath);
+		vars.put("segments_nb", segments_nb);
+		vars.put("segments_db_nb", segments_db_nb);
+		vars.put("tags_nb", tags_nb);
+		
+		
+		Viewable view = new Viewable("/info", vars);
+				
+		return view;
+	}
+	
+}
--- a/src/fr/iri/thd/sonyengine/web/ServletContainer.java	Wed Mar 24 12:41:26 2010 +0100
+++ b/src/fr/iri/thd/sonyengine/web/ServletContainer.java	Tue Mar 30 17:53:36 2010 +0200
@@ -1,10 +1,17 @@
 package fr.iri.thd.sonyengine.web;
 
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
 
+import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.ws.rs.core.Application;
 
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.PropertyConfigurator;
+
 import thd.ThdEngine;
 
 import com.sleepycat.persist.EntityCursor;
@@ -17,12 +24,15 @@
 public class ServletContainer extends
 		com.sun.jersey.spi.container.servlet.ServletContainer {
 
+	public static final String INIT_DATABASE_PATH = "initDatabasePath";
+
 	/**
 	 * 
 	 */
 	private static final long serialVersionUID = -447765110849619632L;
 
 	public static final String DB_ENV_ATTRIBUTE = "DB_ENV";
+	public static final String DB_PATH_ATTRIBUTE = "DB_PATH";
 	
 	public ServletContainer() {
 	}
@@ -37,24 +47,66 @@
 
 
 	public void init() throws ServletException {
+		
+		String log4jLocation = this.getInitParameter("log4j-properties-location");
+		ServletContext sc = this.getServletContext();
+
+		if (log4jLocation == null) {
+			System.err.println("*** No log4j-properties-location init param, so initializing log4j with BasicConfigurator");
+			BasicConfigurator.configure();
+		}
+		else {
+			
+			final Properties prop = new Properties();
+			final InputStream propStream = sc.getResourceAsStream(log4jLocation); 
+			if (propStream != null) {
+				try {
+					prop.load(propStream);
+				} catch (IOException e) {
+					System.err.println("*** " + log4jLocation + " file not found, so initializing log4j with BasicConfigurator");
+					BasicConfigurator.configure();
+				}
+				finally {
+					try {
+						propStream.close();
+					}
+					catch (IOException e) {
+						// do nothing
+					}
+				}
+				System.out.println("Initializing log4j with: " + log4jLocation);
+				PropertyConfigurator.configure(prop);
+			}
+			else {
+				System.err.println("*** " + log4jLocation + " file not found, so initializing log4j with BasicConfigurator");
+				BasicConfigurator.configure();
+			}
+		}
+		
 		super.init();
 		
-		String databasePath = this.getInitParameter("initDatabasePath");
+		String databasePath = this.getServletContext().getInitParameter(INIT_DATABASE_PATH);
 		
-		if(databasePath == null)
-			return;
+		if(databasePath == null || databasePath.length() == 0)
+			throw new ServletException("Database path not found (null or empty)");
 
 		File databasePathFile = new File(databasePath);
 		
-		if(!databasePathFile.exists())
-		{
+                try {
+		    if(!databasePathFile.exists())
+		    {
 			databasePathFile.mkdirs();
-		}
+		    }
+                }
+                catch(Exception e) {
+                    throw new ServletException("Unable to create database path " + databasePath, e);
+                }
 		DbEnv env = new DbEnv();
 		env.setup(databasePathFile, false, true);
 		
 		// set DbEnv in servlet context
-		this.getServletContext().setAttribute(ServletContainer.DB_ENV_ATTRIBUTE, env);
+		sc.setAttribute(ServletContainer.DB_ENV_ATTRIBUTE, env);
+		sc.setAttribute(ServletContainer.DB_PATH_ATTRIBUTE, databasePath);
 		
 		//load all entities
 		DataAccessor da = new DataAccessor(env.getEntityStore());