Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/delibero.git

New servlets for handling business logic.

AuthorDave Jarvis <email>
Date2015-01-20 22:29:21 GMT-0800
Commit9a483316459768ed5639ed859f1668ba1a39fbaf
Parent9314aa4
build.gradle
}
+task createServletMap( type: JavaExec ) {
+ main = "net.sf.saxon.Transform"
+ classpath = configurations.runtime
+ args "-s:source/xsl/menu/menu.xml", "-xsl:source/xsl/servlet/servlet.xsl"
+}
+
buildMenu.dependsOn( copyLibraries )
+run.dependsOn( createServletMap )
run.dependsOn( buildMenu )
run.dependsOn( copyResources )
resources/auth.properties
+#
+# Realm configuration to give Shiro an LDAP connection.
+#
+[main]
+#ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm
+#ldapRealm.userDnTemplate = uid={0},ou=users,dc=company,dc=com
+#ldapRealm.contextFactory.url = ldap://ldapHost:389
+#ldapRealm.contextFactory.authenticationMechanism = DIGEST-MD5
+
+# Authentication to use for HTTP GET requests
+get_auth = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
+
+# Authentication to use for HTTP POST requests
+post_auth = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
+
+#authc.loginUrl = /app/login
+#authc.successUrl = /app/home
+
+#authc.usernameParam = account
+#authc.passwordParam = password
+
+[urls]
+#/app/login = authc
+#/app/edit/** = authc
+
+[users]
+admin = password
+
source/java/to/discuss/App.java
-/**
- * MIT License
- *
- * Copyright 2015 White Magic Software, Ltd.
- */
-package to.discuss;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import javax.servlet.ServletException;
-
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-// Include the status codes.
-import static javax.servlet.http.HttpServletResponse.*;
-
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.Transformer;
-
-import org.apache.shiro.subject.Subject;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.authc.UsernamePasswordToken;
-import org.apache.shiro.web.util.SavedRequest;
-import org.apache.shiro.web.util.WebUtils;
-
-import to.discuss.util.AppURIResolver;
-
-/**
- * Main HTTP request handler for /app.
- */
-@SuppressWarnings("serial")
-public class App extends HttpServlet implements Base {
- private HttpServletRequest request;
- private HttpServletResponse response;
-
- private int responseStatus = SC_OK;
-
- public App() {
- }
-
- protected synchronized void doPost(
- HttpServletRequest request,
- HttpServletResponse response ) throws IOException, ServletException
- {
- Subject user = SecurityUtils.getSubject();
-
- String u = request.getParameter( "account" );
- String p = request.getParameter( "password" );
-
- AuthenticationToken token = new UsernamePasswordToken( u, p );
-
- try {
- user.login( token );
- }
- catch( Exception e ) {
- return;
- }
-
- SavedRequest s = WebUtils.getAndClearSavedRequest( request );
- response.sendRedirect( s.getRequestUrl() );
- }
-
- protected void doGet( HttpServletRequest request,
- HttpServletResponse response ) throws ServletException
- {
- setRequest( request );
- setResponse( response );
-
- try {
- sendHeader();
- sendContent();
- }
- catch( Exception e ) {
- throw new ServletException( e );
- }
- }
-
- /**
- * Writes the header information.
- */
- protected void sendHeader() throws Exception {
- getResponse().setContentType( getContentType() );
- getResponse().setStatus( getResponseStatus() );
- }
-
- /**
- * Returns the default content type.
- *
- * @return "text/html"
- */
- protected String getContentType() {
- return "text/html";
- }
-
- /**
- * Returns the default character encoding.
- *
- * @return "utf-8"
- */
- protected String getEncoding() {
- return "utf-8";
- }
-
- /**
- * Retrieves the document requested by the user and transmits the HTML
- * content to the client.
- */
- private void sendContent() throws Exception {
- //Subject user = SecurityUtils.getSubject();
-
- Transformer transformer = getTransformer();
- transformer.setOutputProperty( OutputKeys.ENCODING, getEncoding() );
- transformer.transform( getDocument(), getResultStream() );
- }
-
- protected Result getResultStream() throws IOException {
- return new StreamResult( getResponse().getOutputStream() );
- }
-
- protected Source getDocument() throws Exception {
- return openSource( getDocumentFilename() );
- }
-
- protected Source openSource( String filename ) throws IOException {
- return new StreamSource( open( filename ) );
- }
-
- private String getDocumentFilename() {
- return String.format( "database%s%s.xml", FILE_SEP, getAppName() );
- }
-
- protected String getStylesheetFilename() {
- return "xsl" + FILE_SEP + "common.xsl";
- }
-
- private Source getStylesheet() throws Exception {
- return openSource( getStylesheetFilename() );
- }
-
- protected TransformerFactory getTransformerFactory() {
- TransformerFactory factory = TransformerFactory.newInstance();
- factory.setURIResolver( new AppURIResolver( this ) );
-
- return factory;
- }
-
- protected Transformer getTransformer() throws Exception {
- return getTransformerFactory().newTransformer( getStylesheet() );
- }
-
- /**
- * Returns the app name, in lowercase.
- *
- * The application name is the first word after "/app", such as "home"
- * in "/app/home" or "synopsis" in "/app/home/synopsis/0". This could
- * also use String.split( "/" ), but regexes are slower than loops.
- *
- * @return The application name without slashes.
- */
- public String getAppName() {
- String path = getRequestPathInfo();
-
- // Detect the first leading slash.
- int index = path.indexOf( '/' );
-
- // Remove the leading slash.
- path = path.substring( index + 1 );
-
- // See if the application name is bracked with slashes (e.g., /home/).
- index = path.indexOf( '/' );
-
- // Extract the application name and remove anything after the trailing
- // slash that might follow the application name.
- return path.substring( 0, index > 0 ? index : path.length() );
- }
-
- /**
- * Returns the numeric identifier at application URL end.
- *
- * @return 0 if the identifier could not be found.
- */
- public long getAppId() {
- long result;
-
- try {
- String path = getRequestPathInfo();
- // Everything after the last slash is a potential identifier.
- result = Long.parseLong( path.substring( path.lastIndexOf( '/' ) + 1 ) );
- }
- catch( Exception e ) {
- result = 0;
- }
-
- return result;
- }
-
- /**
- * Returns the URL after "/app".
- *
- * @return A non-null string.
- */
- protected String getRequestPathInfo() {
- return getRequest().getPathInfo();
- }
-
- private void setRequest( HttpServletRequest request ) {
- this.request = request;
- }
-
- private HttpServletRequest getRequest() {
- return this.request;
- }
-
- private void setResponse( HttpServletResponse response ) {
- this.response = response;
- }
-
- private HttpServletResponse getResponse() {
- return this.response;
- }
-
- /**
- * Return HTTP response status to return to the client.
- *
- * @return An HTTP status code (200 OK by default).
- */
- private int getResponseStatus() {
- return this.responseStatus;
- }
-
- /**
- * Set HTTP response status to return to the client.
- *
- * @param responseStatus The status code to send to the client.
- */
- private void setResponseStatus( int responseStatus ) {
- this.responseStatus = responseStatus;
- }
-}
-
source/java/to/discuss/Main.java
*/
public class Main implements Base {
- private static final String PACKAGE_NAME = Main.class.getPackage().getName();
-
public void run() throws Exception {
Server server = new Server( 8080 );
/**
* Configures the servlet mapping (classes to relative URI paths). This
- * reads from the "servlets.properties" file.
+ * reads from the "servlet.properties" file.
*
* @param context The servlet context (for mapping servlets to URIs).
* @see configureServletDefault#ServletContextHandler
*/
protected void configureServletMap( ServletContextHandler context )
throws Exception {
- context.addServlet( App.class, "/app/*" );
+ Map<String, String> servletMap = getServletMap();
+
+ for( String servlet : servletMap.keySet() ) {
+ String className = String.format( "%s.%s", getPackageName(), servlet );
+ String path = String.format( "%s/*", servletMap.get( servlet ) );
+
+ context.addServlet( className, path );
+ }
}
DefaultServlet staticServlet = new DefaultServlet();
context.addServlet( new ServletHolder( staticServlet ), "/*" );
+ }
+
+ /**
+ * Returns the mapping of servlet class names to URI paths.
+ *
+ * @return A non-null map.
+ */
+ private Map<String, String> getServletMap() throws Exception {
+ return getPropertyMap( "servlet.properties" );
}
+ /**
+ * Returns the system properties to set. This can be used to set the
+ * XML parser, for example.
+ *
+ * @return A non-null map.
+ */
private Map<String, String> getSystemPropertyMap() throws Exception {
return getPropertyMap( "system.properties" );
private Map<String, String> getPropertyMap( String file ) throws Exception {
return (new ResolvedProperties( open( file ) )).asMap();
+ }
+
+ /**
+ * Returns the name of the package that contains the servlets.
+ */
+ private String getPackageName() {
+ return getClass().getPackage().getName() + ".servlet";
}
source/java/to/discuss/servlet/Account.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/account.
+ */
+@SuppressWarnings("serial")
+public class Account extends App {
+ public Account() {
+ }
+}
+
source/java/to/discuss/servlet/App.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.servlet.ServletException;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+// Include the status codes.
+import static javax.servlet.http.HttpServletResponse.*;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.Transformer;
+
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.web.util.SavedRequest;
+import org.apache.shiro.web.util.WebUtils;
+
+import to.discuss.Base;
+import to.discuss.util.AppURIResolver;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Main HTTP request handler for /app.
+ */
+@SuppressWarnings("serial")
+public class App extends HttpServlet implements Base {
+ private static final Logger LOG = LoggerFactory.getLogger( App.class );
+
+ private HttpServletRequest request;
+ private HttpServletResponse response;
+
+ private int responseStatus = SC_OK;
+
+ public App() {
+ }
+
+/*
+ protected synchronized void doPost(
+ HttpServletRequest request,
+ HttpServletResponse response ) throws IOException, ServletException
+ {
+ Subject user = SecurityUtils.getSubject();
+
+ String u = request.getParameter( "account" );
+ String p = request.getParameter( "password" );
+
+ AuthenticationToken token = new UsernamePasswordToken( u, p );
+
+ try {
+ user.login( token );
+
+ SavedRequest s = WebUtils.getAndClearSavedRequest( request );
+
+ if( s != null ) {
+ response.sendRedirect( s.getRequestUrl() );
+ }
+ }
+ catch( Exception e ) {
+ doGet( request, response );
+ }
+ }
+*/
+
+ protected void doGet( HttpServletRequest request,
+ HttpServletResponse response ) throws ServletException
+ {
+ setRequest( request );
+ setResponse( response );
+
+ try {
+ sendHeader();
+ sendContent();
+ }
+ catch( Exception e ) {
+ throw new ServletException( e );
+ }
+ }
+
+ /**
+ * Writes the header information.
+ */
+ protected void sendHeader() throws Exception {
+ getResponse().setContentType( getContentType() );
+ getResponse().setStatus( getResponseStatus() );
+ }
+
+ /**
+ * Returns the default content type.
+ *
+ * @return "text/html"
+ */
+ protected String getContentType() {
+ return "text/html";
+ }
+
+ /**
+ * Returns the default character encoding.
+ *
+ * @return "utf-8"
+ */
+ protected String getEncoding() {
+ return "utf-8";
+ }
+
+ /**
+ * Retrieves the document requested by the user and transmits the HTML
+ * content to the client.
+ */
+ private void sendContent() throws Exception {
+ //Subject user = SecurityUtils.getSubject();
+
+ Transformer transformer = getTransformer();
+ transformer.setOutputProperty( OutputKeys.ENCODING, getEncoding() );
+ transformer.transform( getDocument(), getResultStream() );
+ }
+
+ protected Result getResultStream() throws IOException {
+ return new StreamResult( getResponse().getOutputStream() );
+ }
+
+ protected Source getDocument() throws Exception {
+ return openSource( getDocumentFilename() );
+ }
+
+ protected Source openSource( String filename ) throws IOException {
+ return new StreamSource( open( filename ) );
+ }
+
+ private String getDocumentFilename() {
+ return String.format( "database%s%s.xml", FILE_SEP, getAppName() );
+ }
+
+ protected String getStylesheetFilename() {
+ return "xsl" + FILE_SEP + "common.xsl";
+ }
+
+ private Source getStylesheet() throws Exception {
+ return openSource( getStylesheetFilename() );
+ }
+
+ protected TransformerFactory getTransformerFactory() {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ factory.setURIResolver( new AppURIResolver( this ) );
+
+ return factory;
+ }
+
+ protected Transformer getTransformer() throws Exception {
+ return getTransformerFactory().newTransformer( getStylesheet() );
+ }
+
+ /**
+ * Returns the app name, in lowercase.
+ *
+ * @return The application name without slashes.
+ */
+ public String getAppName() {
+ return getClass().getSimpleName().toLowerCase();
+ }
+
+ private void setRequest( HttpServletRequest request ) {
+ this.request = request;
+ }
+
+ private HttpServletRequest getRequest() {
+ return this.request;
+ }
+
+ private void setResponse( HttpServletResponse response ) {
+ this.response = response;
+ }
+
+ private HttpServletResponse getResponse() {
+ return this.response;
+ }
+
+ /**
+ * Return HTTP response status to return to the client.
+ *
+ * @return An HTTP status code (200 OK by default).
+ */
+ private int getResponseStatus() {
+ return this.responseStatus;
+ }
+
+ /**
+ * Set HTTP response status to return to the client.
+ *
+ * @param responseStatus The status code to send to the client.
+ */
+ private void setResponseStatus( int responseStatus ) {
+ this.responseStatus = responseStatus;
+ }
+}
+
source/java/to/discuss/servlet/Discuss.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/discuss.
+ */
+@SuppressWarnings("serial")
+public class Discuss extends App {
+ public Discuss() {
+ }
+}
+
source/java/to/discuss/servlet/Edit.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/edit.
+ */
+@SuppressWarnings("serial")
+public class Edit extends App {
+ public Edit() {
+ }
+}
+
source/java/to/discuss/servlet/Flag.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/flag.
+ */
+@SuppressWarnings("serial")
+public class Flag extends App {
+ public Flag() {
+ }
+}
+
source/java/to/discuss/servlet/Home.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/home.
+ */
+@SuppressWarnings("serial")
+public class Home extends App {
+ public Home() {
+ }
+}
+
source/java/to/discuss/servlet/Login.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/login.
+ */
+@SuppressWarnings("serial")
+public class Login extends App {
+ public Login() {
+ }
+}
+
source/java/to/discuss/servlet/Logout.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/logout.
+ */
+@SuppressWarnings("serial")
+public class Logout extends App {
+ public Logout() {
+ }
+}
+
source/java/to/discuss/servlet/New.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/new.
+ */
+@SuppressWarnings("serial")
+public class New extends App {
+ public New() {
+ }
+}
+
source/java/to/discuss/servlet/Proposal.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/proposal.
+ */
+@SuppressWarnings("serial")
+public class Proposal extends App {
+ public Proposal() {
+ }
+}
+
source/java/to/discuss/servlet/Refute.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/refute.
+ */
+@SuppressWarnings("serial")
+public class Refute extends App {
+ public Refute() {
+ }
+}
+
source/java/to/discuss/servlet/Resources.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/resources.
+ */
+@SuppressWarnings("serial")
+public class Resources extends App {
+ public Resources() {
+ }
+}
+
source/java/to/discuss/servlet/Success.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/success.
+ */
+@SuppressWarnings("serial")
+public class Success extends App {
+ public Success() {
+ }
+}
+
source/java/to/discuss/servlet/Support.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/support.
+ */
+@SuppressWarnings("serial")
+public class Support extends App {
+ public Support() {
+ }
+}
+
source/java/to/discuss/servlet/Synopsis.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/synopsis.
+ */
+@SuppressWarnings("serial")
+public class Synopsis extends App {
+ public Synopsis() {
+ }
+}
+
source/java/to/discuss/servlet/Tags.java
+/**
+ * MIT License
+ *
+ * Copyright 2015 White Magic Software, Ltd.
+ */
+package to.discuss.servlet;
+
+/**
+ * Main HTTP request handler for /app/tags.
+ */
+@SuppressWarnings("serial")
+public class Tags extends App {
+ public Tags() {
+ }
+}
+
source/java/to/discuss/util/AppURIResolver.java
import javax.xml.transform.stream.StreamSource;
-import to.discuss.App;
import to.discuss.Base;
+import to.discuss.servlet.App;
/**
source/xsl/servlet/servlet.xsl
+<?xml version='1.0' encoding='utf-8'?>
+<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+
+<xsl:output indent="yes" method="text" encoding="utf-8"/>
+
+<xsl:strip-space elements="*"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="menus">
+ <xsl:apply-templates select="items"/>
+</xsl:template>
+
+<xsl:template match="items">
+<xsl:result-document method="text" href="build/resources/servlet.properties">
+<xsl:text># Machine generated: change via servlet.xsl.&#xa;</xsl:text>
+<xsl:text>#&#xa;</xsl:text>
+<xsl:text># classname = url path&#xa;</xsl:text>
+<xsl:text>App=/app</xsl:text>
+<xsl:text>&#xa;</xsl:text>
+<xsl:apply-templates/>
+</xsl:result-document>
+</xsl:template>
+
+<xsl:template match="item">
+ <xsl:sequence
+ select="concat(upper-case(substring(@link,1,1)),substring(@link, 2))"/>
+ <xsl:text>=${App}/</xsl:text>
+ <xsl:value-of select="@link"/>
+ <xsl:text>&#xa;</xsl:text>
+</xsl:template>
+
+<!-- Ignore /menus/items -->
+<xsl:template match="*"/>
+
+</xsl:stylesheet>
Delta561 lines added, 256 lines removed, 305-line increase