A Walking Tour of the Struts MailReader Demonstration Application
This article is meant to introduce a new user to Struts by "walking through" an application. See the Struts Users Guide and Strut's API for more documentation.
The MailReader application is based on the 1.3.0 build of Struts. To follow along, you should install the MailReader application on your own development workstation (e.g. localhost).
This article assumes the reader has a basic understanding of the Java language, JavaBeans, web applications, and JavaServer Pages. For background on these technologies, see the Preface to the Struts User Guide.
The Struts App subproject includes four applications: struts-blank, struts-cookbook, struts-examples, and struts-mailreader. This document walks through struts-mailreader, also known as the "MailReader Demonstration Application".
The premise of the MailReader is that it is the first iteration of a portal application. This version allows users to register themselves and maintain a set of accounts with various mail servers. If completed, the application would let users read mail from their accounts.
The MailReader application demonstrates registering with an application, logging into an application, maintaining a master record, and maintaining child records. This document walks through the constructs needed to do these things, including the server pages, Java classes, and configuration elements.
For more about the MailReader, including alternate implementations and a set of formal Use Cases, please visit the Struts University MailReader site.
JAAS - Note that for compatibility and ease of deployment, the MailReader uses "application-based" authorization. However, use of the standard Java Authentication and Authorization Service (JAAS) is recommended for most applications. (See the Preface to the Struts Action User Guide for more about authentification technologies.)
The walkthrough starts with how the initial welcome page is displayed, and then steps through logging in, adding and editing subscriptions, and creating a new registration.
Howdy
A web application, like any other web site, can specify a list of welcome pages. When you open a web application without specifying a particular page, a welcome page is used by default.
web.xml
When a web application loads, the container reads and parses the "Web Application Deployment Descriptor", or web.xml file. The Struts Action Framework plugs into a web application via a controller servlet. Like any servlet, the Action servlet is deployed via the web.xml.
web.xml - The Web Application Deployment Descriptor
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Struts MailReader Application</display-name>  <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>  <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>  <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>  <error-page> <exception-type>java.lang.Exception</exception-type> <location>/Error.jsp</location> </error-page> </web-app>
Among other things, the web.xml specifies the "Welcome File List" for an application. When a web address refers to a directory rather than an individual file, the container consults the Welcome File List for the name of a page to open by default.
Albeit, most Struts applications do not refer to physical pages, but to "virtual pages" called actions. The actions are listed in a configuration file. Actions contain code that we want to be run before a page is displayed. An accepted practice in the Struts Action community is to never link directly to server pages, but only to Struts actions. By linking to actions, developers can "rewire" an application without editing the server pages.
Best Practice:
"Link actions not pages."
Unless you are using Java 1.5, actions cannot be specified as a welcome page. So, in the case of a welcome page, how do we follow the Struts best practice of navigating through actions rather than pages?
One solution is to use a server page to "bootstrap" a Struts action. A Java web application recognizes the idea of "forwarding" from one page to another page (or action). We can register the usual "index.jsp" as the welcome page and have it forward to a "Welcome" action.
MailReader's index.jsp
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <logic:redirect action="/Welcome"/>
At the top of the page, we import the "struts-logic" JSP tag library. (For more about the Struts JSP tags, see the Struts Taglib website.) The page itself consists of a single tag that redirects to the "Welcome" action. The tag inserts the actual web address for the redirect when the page is rendered. But, where does the tag find the actual address to insert?
Welcome.do
The list of actions, along with other components, are registered through one or more Struts Action configuration files. The configuration files are written as XML documents and processed when the application starts. If we just wanted to forward to the welcome page, we could use a simple configuration element.
A simple "forward thru" action element
 <action path="/Welcome" forward="/Welcome.jsp" />
If someone asked for the Welcome action ("/Welcome.do"), the welcome.jsp page would be displayed in return.
But if we peek at the configuration file for the MailReader, we find a slightly more complicated XML element for the Welcome action.
The Welcome action element
 <action path="/Welcome" type="org.apache.struts.apps.mailreader.actions.WelcomeAction" > <forward name="Success" path="/Welcome.jsp" /> </action>
Here, the WelcomeAction Java class executes whenever someone asks for the Welcome action. As it completes, the Action class can select which "result" is displayed. One available result is "Success". Another available result, defined at a global scope, is "Failure". But the Action class doesn't need to know the path to the result, or even if they are server pages. The Action class can select the appropriate result just by using names like "Success" or "Failure".
WelcomeAction
OK ... but why would a WelcomeAction want to choose between Success and Failure?
The MailReader application retains a list of users along with their email accounts. The application stores this information in a database. If the application can't connect to the database, the application can't do its job. So before displaying the welcome page, the class checks to see if the database is available. The MailReader is also an internationalized application. So, the WelcomeAction checks to see if the message resources are available too. If both resources are available, the class forwards to the "Success" path. Otherwise, it forwards to the "Failure" path so that the appropriate error messages can be displayed.
global-forwards
MailReader's global-forward element
 <global-forwards> <forward name="Logoff" path="/Logoff.do"/> <forward name="Logon" path="/Logon.do"/> <forward name="Failure" path="/Error.jsp" /> </global-forwards>
As mentioned, "Failure" is defined in a global scope. Other actions may have trouble connecting to the database later, or other unexpected errors may occur. The MailReader defines the "Failure" result as a Global Forward, so that any action can use it.
MemoryDatabasePlugIn.java
The database is exposed as an object stored in application scope. The database object is based on an interface. Different implementations of the database could be loaded without changing the rest of the application. But how is the database object loaded in the first place?
One section of the Struts configuration is devoted to "PlugIns". When a Struts application loads, it also loads whatever PlugIns are specified in its configuration. The PlugIn interface is quite simple.
org.apache.struts.action.PlugIn
public interface PlugIn { void destroy(); void init(ActionServlet servlet, ModuleConfig config) throws ServletException; }
You can use PlugIns to do anything that might need to be done when your application loads. The PlugIn is also notified when the application shuts down, so you can release any allocated resources.
The Database PlugIn element
<plug-in className="org.apache.struts.apps.mailreader.plugin. MemoryDatabasePlugIn"> <set-property property="pathname" value="/WEB-INF/database.xml"/> </plug-in>
By default, the MailReader application loads a "MemoryDatabase" implementation of the UserDatabase. MemoryDatabase stores the database content as a XML document, which is parsed and loaded as a set of nested hashtables. The outer table is the list of user objects, each of which has its own inner hashtable of subscriptions. When you register, a user object is stored in this hashtable ... and when you login, the user object is stored within the session context.
The database comes seeded with a sample user. If you check the database.xml file under WEB-INF, you'll see the sample user described in XML.
The "seed" user element from the MailReader database.xml
<user username="user"<EMAIL_ADDRESS>fullName="John Q. User" password="pass"> <subscription host="mail.hotmail.com" autoConnect="false" password="bar" type="pop3" username="user1234"> </subscription> <subscription host="mail.yahoo.com" autoConnect="false" password="foo" type="imap" username="jquser"> </subscription> </user>
The "seed" user element creates a registration record for "John Q. User", with the detail for his hotmail account (or "subscription").
MessageResources.properties
Another section of the Struts configuration loads the message resources for the application. If you change a message in the resource, and then reload the application, the change will appear throughout the application. If you provide message resources for additional locales, you can internationalize your application.
The MailReader message-resources element
<message-resources parameter="org.apache.struts.apps.mailreader.resources.ApplicationResources"/>
The "ApplicationResources" parameter refers to a standard properties text file. The resource might be embedded in a JAR or kept under the WEB-INF/classes folder. MailReader uses the classes folder, which means its working copy of the ApplicationResources can be found at
./WEB-INF/classes/org/apache./struts/apps/mailreader/resources/ApplicationResources"
The first time a page needs one of the resources, Struts Action loads and caches the properties file, so that the framework does not need to read the text file a second time.
ApplicationResource entries used by the Welcome page
index.heading=MailReader Demonstration Application Options index.logon=Log on to the MailReader Demonstration Application index.registration=Register with the MailReader Demonstration Application index.title=MailReader Demonstration Application index.tour=A Walking Tour of the MailReader Demonstration Application
The MailReader application uses a second set of message resources for non-text elements.
The MailReader alternate message-resources element
<message-resources parameter="org.apache.struts.apps.mailreader.resources.AlternateApplicationResources" key="alternate"/>
The "key" element can be used to access this resource bundle rather than the default bundle.
Welcome page
After confirming that the necessary resources exist, the WelcomeAction forwards to the Welcome page.
Welcome.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>   <title><bean:message key="index.title"/></title> <link rel="stylesheet" type="text/css" href="base.css" />
<bean:message key="index.heading"/>

 <bean:message key="index.registration"/>

<bean:message key="index.logon"/>

Change Language

English

Japanese

Russian

<bean:message key="index.tour"/>

At the top of the Welcome page, there are several directives that load the Struts tag libraries. These are just the usual red tape that goes with any JSP file. The rest of the page utilizes three Struts JSP tags: "bean:message", "html:link", and "html:img".
The bean:message tag inserts a message from the MessageResources we mentioned in the last section. The MailReader comes with support for three locales: English (the default), Russian, and Japanese. If the Struts Action locale setting is changed for a user, the bean:message tag will render messages from that locale's property bundle instead.
The html:link tag does double duty. First, you can refer to an action or forward stored in the Struts configuration, and the tag will insert the corresponding path when the page is rendered. This makes it easy to "rewire" an application without touching all the pages. Second, the link tag will "URL encode" the hyperlink to maintain the client session. Your application can maintain client state without requiring cookies.
 (If you are using Internet Explorer and try this, be sure you reset cookies for the appropriate security zone, and that you disallow "per-session" cookies.)
The html:img tag renders an img tag. When necessary, the src URI is encoded as it is with the link tag. In this case, the tag inserts the src path from the "alternate" MessageResource bundle, along with the text for the alt element.
In the span of a single request for the Welcome page, Struts has done quite a bit already:
- Confirmed that required resources were loaded during initialization.
- Written all the page headings and labels from internationalized message resources.
- Automatically URL-encoded paths as needed.
When rendered, the Welcome page lists two menu options: one to register with the application and one to login in (if you have already registered). Let's follow the Login link first.
Logon Page
If you choose the Logon link, and all goes well, the Logon action forwards control to the Logon.jsp page. The Logon page displays a form that accepts a username and password. You can use the default username and password to logon (user and pass) if you like.
Note that both the username and password are case sensitive. Better yet, try omitting or misspelling the username and password in various combinations to see how the application reacts.
Login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>    <title><bean:message key="logon.title"/></title>

  <bean:message key="prompt.username"/>:

  <bean:message key="prompt.password" bundle="alternate"/>:

    <jsp:include page="Footer.jsp" />
We saw some of these tags on the Welcome page. Let's focus on the new tags.
The first new tag on the logon page is html:errors. The credentials you entered are validated and processed by a "LogonAction" class. If the credentials are incorrect, the LogonAction posts an appropriate error message and forwards back to the input page. If the html:errors tag sees that one or more messages were posted, the tag ouputs the messages to the page. The text of the messages can be specified in the MessageResource bundle, making them easy to localize.
The second new tag is html:form. This tag renders a html form tag. The "action" attribute tells the tag to use "SubmitLogon.do" for the form's action. The "focus" attribute tells the tag to generate a little Javascript into the form that sets its focus to the "username" field. The "onsubmit" attribute tells the form to run a Javascript when the form is submitted. (Just like the corresponding attribute on the standard form tag.)
Within the html:form tag, we see five more new tags: "html:text", "html:password", "html:submit", "html:reset", and "html:javascript".
The html:text tag renders a "input type=text" tag. The "property" attribute becomes the input tag's "name" attribute.
The html:password tag renders a "input type=password" tag. The "redisplay" attribute tell the tag not to render the password back into the file, if the submit fails. The html:submit and html:reset tags render buttons of the corresponding types.
Following the form is a html:javascript tag. This tag works with the Struts Validator component to generate a JavaScript that can validate input before it is submitted to the LogonAction.
Tip:
Most of these tags have many more options than the ones we use in this application. For the complete documentation for each tag, see the Tag Developer Guides in the Struts Taglib documentation bundle.
But, how do these tags know so much? How does the Javascript tag know what scripts to write? How do the text and password tags know what values to redisplay?
For the answers, we need to turn back to the Struts Action Framework configuration files, "struts-config.xml" and "validation.xml".
struts-config.xml
The Struts configuration file is parsed by the ActionServlet when the application first load.
web.xml -- Action Servlet Configuration
<servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
The SubmitLogon action element
 <action path="/SubmitLogon" type="org.apache.struts.apps.mailreader.actions.LogonAction" name="LogonForm" scope="request" validate="request" input="Logon"> <exception key="expired.password" type="org.apache.struts.apps.mailreader.dao.ExpiredPasswordException" path="/ChangePassword.jsp"/> <forward name="Success" path="/MainMenu.do"/> </action>
We saw the path and type attributes in the Welcome action. Let's look at the new attributes: "name", "scope", "input", and "exception".
The "name" attribute
The name attribute specifies something Struts Action calls an "ActionForm". The ActionForm buffers input from a form and delivers it to an Action class as an object. The ActionForm can also be used to validate input. If validation fails, the tags can rewrite the input values from the ActionForm.
The ActionForms are defined in the "form-beans" section of struts-config.
ActionForms can be "conventional" or "dynamic". MailReader uses dynamic ActionForms. Rather than cobble up an actual JavaBean class, we specify the properties the ActionForm can accept in the configuration file.
The form-bean element for LogonForm
 <form-bean name="LogonForm" extends="BaseForm"/>
Hmmmm. That doesn't seem to tell us much. The LogonForm "extends" the BaseForm, but doesn't add any attributes. What about the BaseForm element that LogonForm extends?
BaseForm - An "abstract" form-bean
 <form-bean name="BaseForm" type="org.apache.struts.validator.DynaValidatorForm"> <form-property name="username" type="java.lang.String"/> <form-property name="password" type="java.lang.String"/> <form-property name="task" type="java.lang.String" initial="Create"/> </form-bean>
Note:
Extends - In the Struts configuration file, we can use the "extends" attribute to adopt default settings from another element. Extends makes using XML elements more like object-orientated programming. You can setup a base element, and then only specify the behavior that changes.
Struts creates the ActionForms automatically, regardless of whether the form-bean is conventional or dynamic. The ActionForm lets us specify which properties we want to extract from the incoming request. If a property is not specified by the ActionForm, the value is not automatically transferred from the request, validated, or passed to the Action class.
The "scope" attribute
The scope attribute in the "SubmitLogon" action element tells the controller whether to store the ActionForm in the request, rather than in the user's session.
Best Practice:
Use request scope for single-page forms that contain all the properties needed by the Action. There is usually no need to maintain form input across requests.
The "validate" attribute
The validate attribute controls whether the framework will automatically validate the ActionForm. Conventional ActionForms have a stub "validate" method that you can implement. MailReader uses the Validator framework instead, so the validations are specified in another configuration file.
The "input" attribute
If validation fails, Struts looks for the forward specified by the input attribute. In this case, invoking the global "Logon" forward sends control back to the Logon page.
The "exception" element
Within the SubmitLogon action element is another new element, exception. When a user logons on, it's possible that an "ExpiredPasswordException" will be thrown. Should this happen, Struts will catch the exception and send control to the "ChangePassword" action.
Change Password screen
Your password has expired. Please ask the system administrator to change it. Try Again
OK, it's not the greatest "Change Password" screen -- but, remember, this is still the first iteration!
validations.xml
In the Logon page, we mentioned that the html:javascript tag confers with the Struts Validator components. The Validator is configured through another XML document, the validation.xml.
Validator element for LogonForm
<form name="LogonForm"> <field property="username" depends="required"> <arg key="prompt.username"/> </field> <field property="password" depends="required, minlength,maxlength"> <arg key="prompt.password"/> <arg key="${var:minlength}" name="minlength" resource="false"/> <arg key="${var:maxlength}" name="maxlength" resource="false"/> <var> <var-name> maxlength </var-name> <var-value> 16 </var-value> </var> <var> <var-name> minlength </var-name> <var-value> 3 </var-value> </var> </field> </form>
The field elements correspond to the ActionForm properties. The username field element says it depends on the "required" validator. If the username is blank or absent, validation will fail and an error message is automatically generated.
The password field (or property) is also required. In addition, it must also pass the "maxlength" and "minlength" validations. Here, the minimum length is three characters and the maximum length is sixteen. If the length of the password doesn't meet these criteria, a corresponding error message is generated. Of course, the messages are generated from the MessageResource bundles and are easy to localize.
LogonAction.java
If validation passes, the LogonForm object is passed to the LogonAction as a parameter. The LogonAction interacts with the database to see if the credentials are valid. If so, the user is logged on, and control passes to the "success" forward. Otherwise, control is forwarded to the input page and the list of error messages displayed.
LogonAction.java
public final class LogonAction extends BaseAction { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // Retrieve user String username = doGet(form, USERNAME); String password = doGet(form, PASSWORD); ActionMessages errors = new ActionMessages(); User user = doGetUser(username,password,errors); // Report back any errors, and exit if any if (!errors.isEmpty()) { this.saveErrors(request, errors); return (mapping.getInputForward()); } // Cache user object in session to signify logon doCacheUser(request,user); // Done return doFindSuccess(mapping); } }
LogonAction extends another Action class, BaseAction. The BaseAction class provides a number of helper methods, all of which are prefixed with "do". The doCacheUser method, for example, stores the user object in the session, and logs the event, if the logging level is set to debug.
BaseAction.doCacheUser
void doCacheUser(HttpServletRequest request, User user) { HttpSession session = request.getSession(); session.setAttribute(Constants.USER_KEY, user); if (log.isDebugEnabled()) { log.debug( "LogonAction: User '" + user.getUsername() + "' logged on in session " + session.getId()); } }
Because our ActionForm is a DynaActionForm, we can't access or change the properties directly using methods like "getUsername". To make working with DynaActionForm properties easier, BaseAction provides two simple helper methods, doGet and doSet. These are utility methods that you caould use in any Struts application.
BaseAction.doGet and doSet
protected String doGet(ActionForm form, String property) { String initial; try { initial = (String) PropertyUtils.getSimpleProperty(form, property); } catch (Throwable t) { initial = null; } String value = null; if ((initial !=null) && (initial.length()>0)) { value = initial.trim(); if (value.length()==0) value = null; } return value; } protected boolean doSet(ActionForm form, String property, String value) { try { DynaActionForm dyna = (DynaActionForm) form; dyna.set(property,value); } catch (Throwable t) { return false; } return true; }
LogonAction uses two other BaseAction helpers: "doGetUser" and "doFindSuccess".
BaseAction.doGetUser
User doGetUser(UserDatabase database, String username, String password, ActionMessages errors) throws ExpiredPasswordException { User user = null; if (database == null){ errors.add( ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.database.missing")); } else { user = database.findUser(username); if ((user != null) && !user.getPassword().equals(password)) { user = null; } if (user == null) { errors.add( ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.password.mismatch")); } } return user; }
The doGetUser helper does the real work of the LogonAction. The "doGetUser" method checks the tendered credentials against the database, If there are any issues, like there is not a user by that name, or the password doesn't match, doGetUser passes back the appropriate messages.
The doGet user is another "facade" method. A facade simplifies a complicated call to a business method. Here, doGetUser wrapes the business method with the Error Handling needed by the Mail Reader application.
BaseAction.doFindSuccess
protected ActionForward doFindSuccess (ActionMapping mapping) { if (log.isTraceEnabled()) { log.trace(Constants.LOG_SUCCESS); } return mapping.findForward(Constants.SUCCESS);
The doFindSuccess method is a simple utility but often used. It just checks the mapping for a result named "Success". By using a utility, we can include a logging statement when trace is enabled, and be very sure that everyone knows how to spell "Success". :)
MainMenu.do and MainMenu.jsp
On a successful logon, the Main Menu page displays. If you logged in using the demo account, the page title should be "Main Menu Options for John Q. User". Below this legend should be two links:
- Edit your user registration profile
- Log off MailReader Demonstration Application
If you check the address shown by your browser, you will see that it shows "/SubmitLogon.do" not "/MainMenu.do". The Java servlet platform supports the idea of server-side forwards. When control passed from the SubmitLogon action to the MainMenu action, everything occured server-side. All the browser knows is that we are looking at the result of submitting a form to "/SubmitLogon.do", so that's the address that shows. It doesn't know control passed from one action to another. The difference between server-side forwards and client-side redirects is subtle and often confuses new developers.
If you change the address to "/MainMenu.do" and press enter, the same page will display again, but only because you are logged on. If you bookmark MainMenu.do, log off, and try to return later, the system will force you to logon first.
Let's review the source for the "MainMenu" action mapping, "MainMenuAction.java" class, and the "MainMenu.jsp".
Action mapping element for MainMenu
 <action path="/MainMenu" type="org.apache.struts.apps.mailreader.actions.MainMenuAction"> <forward name="Success" path="/MainMenu.jsp"/> </action>
MainMenuAction.java
public final class MainMenuAction extends BaseAction { public ActionForward execute ( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { User user = doGetUser(request); if (user==null) return doFindLogon(mapping); return doFindSuccess(mapping); } }
MainMenu.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="/tags/app" prefix="app" %> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>   <title><bean:message key="mainMenu.title"/></title> <link rel="stylesheet" type="text/css" href="base.css" />
<bean:message key="mainMenu.heading"/> < bean:write name="user" property="fullName" />

<bean:message key="mainMenu.registration"/>

<bean:message key="mainMenu.logoff"/>

In the MainMenuAction, we find two new helper methods: "doFindLogon" and "doFindSuccess".
The doFindLogon helper locates the "logon" result, and logs the event if trace logging is enabled. If someone has bookmarked "MainMenu.do" and tries to return without logging in, the MainMenuAction sends the request to Logon.do instead.
BaseAction.doFindLogon
protected ActionForward doFindLogon(ActionMapping mapping) { if (log.isTraceEnabled()) { log.trace(Constants.LOG_LOGON); } return mapping.findForward(Constants.LOGON); }
Likewise, doFindSuccess locates the "success" result, and logs the event if trace logging is enabled.
BaseAction.doFindSuccess
protected ActionForward doFindSuccess (ActionMapping mapping) { if (log.isTraceEnabled()) { log.trace(Constants.LOG_SUCCESS); } return mapping.findForward(Constants.SUCCESS); }
The source for MainMenu.jsp also contains a new tag, bean:write. When control passed through the LogonAction, it retrieved a "user" object from the database and stored a reference in "session" scope. This object is a JavaBean with several properties. One property is "fullName". The bean:write tag can find the User bean and print the fullName property for us.
Since the MainMenuAction verifies that the User object exists, the MainMenu page can refer to the object without ado. The application does not reveal the location of any server page on the browser address bar, but if you did happen to know the address for the server page, and you did enter it directly, the tag would throw an exception, and the framework would transfer to the standard error page.
Error.jsp
An unexpected error has occured Cannot find bean: "user" in any scope MailReader Demonstration Application
The MainMenu action doesn't have an exception handler of its own, so it falls back to the standard handler in the MailReader web.xml.
error-page element in web.xml
 <error-page> <exception-type>java.lang.Exception</exception-type> <location>/Error.jsp</location> </error-page>
Meanwhile, The MainMenu page offers two links. One link is to the "Logoff" action. The other is to "EditRegistration". Hmmmm, back on the Welcome page, we also linked to the EditRegistration action to create an account. Which is it? Insert or Update?
EditRegistration.do
If you scan the struts-config for an EditRegisration action, you won't find one. Instead, you will find a "/Edit*" action. The asterisk is a wildcard character that lets you apply a common action configuration to any request that beings with "Edit".
The Wilcard Edit* action and the BaseAction element it extends
<action path="/Edit*" extends="//BaseAction" parameter="Edit" validate="false"/>  <action path="//BaseAction" input="Input" type="org.apache.struts.apps.mailreader.actions.{1} Action" name="{1}Form" scope="request"> <forward name="Success" path="/"{1}.jsp"/> <forward name="Input" path="/"{1}.jsp"/> </action>
The Edit* action extends the "BaseAction" element (as do other Wilcard actions), and provides two attibutes of its own: "validate" and "parameter". Validate we've seen before, but what about "parameter"?
The Action class underlying the EditRegistration action extends a standard Struts class called "MappingDispatchAction". Usually, an Action has one entry point, the "execute" method. Dispatch Actions let you define multiple entry points to an Action. People find Dispatch Actions handy for related actions, like editing or saving the same entity. (In our case, a Registration.)
A MappingDispatchAction uses the parameter attribute to determine which method to use as the entry point. Each dispatch entry point is a separate method, but each method must same signature as execute. In this case, we're telling the framework to call the "Edit" method when this action is invoked.
OK, but how do we know which Action class to call? The "Edit*" action mapping doesn't specify a type attribute.
If you look at the BaseAction mapping, you'll see that it does specify a type attribute, but the class name isn't valid. It contains a "{1}" token instead of the fully qualified class name.
Since the type attribute will be used with a Wildcard action ("/Edit*"), we can use the {1} to represent the first Wildcard replaced in the path. In the case of EditRegistration, the "wild" text would be "Registration", so that's what is plugged into the type statement. Then the EditRegistration action is called, the type becomes "org.apache.struts.apps.mailreader.actions. RegistrationAction".
The same thing will happen for the other markers. The ActionForm name becomes "RegistrationForm". The name of the "Success" server page becomes "Registration.jsp".
The RegistrationForm is a DynaActionForm, much like the LoginForm.
The RegistrationForm form-bean element
 <form-bean name="RegistrationForm" extends="BaseForm"> <form-property name="fromAddress" type="java.lang.String"/> <form-property name="fullName" type="java.lang.String"/> <form-property name="password2" type="java.lang.String"/> <form-property name="replyToAddress" type="java.lang.String"/> </form-bean>
The RegistrationForm extends the BaseForm and adds properties peculiar to the Registration action. When either the Welcome page or MainMenu page link to " EditRegistration", the framework creates the RegistrationForm, autopopulates the form-bean properties from any matching attributes in the request, and invokes the Edit method of the RegistrationAction class.
RegistrationAction.Edit
public ActionForward Edit( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { final String method = Constants.EDIT; doLogProcess(mapping,method); HttpSession session = request.getSession(); User user = doGetUser(session); boolean updating = (user!=null); if (updating) { doPopulate(form,user); } doSaveToken(request); return doFindSuccess(mapping); }
The RegistrationAction.Edit method does most of its work by calling various helper methods, including "doLogProcess", "doGetUser", "doPopulate", and "doSaveToken".
BaseAction.doLogProcess
protected void doLogProcess(ActionMapping mapping, String method) { if (log.isDebugEnabled()) { StringBuffer sb = new StringBuffer(128); sb.append(" "); sb.append(mapping.getPath()); sb.append(":"); sb.append(Constants.LOG_PROCESSING); sb.append(method); log.debug(sb.toString()); } }
MailReader uses Commons Logging from Apache Jakarta. Commons Logging is an API utility that can be used with several different logging systems. The doLogProcess helper is just a wrapper around a logging statement that MailReader uses in several places. All of the MailReader's Dispatch methods call this helper to log when control reaches the method.
BaseAction.doGetUser
protected User doGetUser(HttpSession session) { return (User) session.getAttribute(Constants.USER_KEY); }
Most of the MailReader actions utilize the User object, and so BaseAction encapsulates obtaining the User into the very simple doGetUser helper.
RegistrationAction.doPopulate
private void doPopulate(ActionForm form, User user) throws ServletException { final String title = Constants.EDIT; if (log.isTraceEnabled()) { log.trace(Constants.LOG_POPULATE_FORM + user); } try { PropertyUtils.copyProperties(form, user); DynaActionForm dyna = (DynaActionForm) form; dyna.set(TASK,title); dyna.set(PASSWORD,null); dyna.set(PASSWORD2,null); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t == null) t = e; log.error(LOG_REGISTRATION_POPULATE, t); throw new ServletException(LOG_REGISTRATION_POPULATE, t); } catch (Throwable t) { log.error(LOG_REGISTRATION_POPULATE, t); throw new ServletException(LOG_REGISTRATION_POPULATE, t); } }
The doPopulate helper lives in RegistrationAction rather than BaseAction, since it involves the RegistrationForm, which only the RegistrationAction uses. The main job of doPopulate is to transfer the input values from the ActionForm to the User object. The constants, like "PASSWORD", are defined on RegisrationAction as public constants. These constants document the property names specified in the Struts configuration for the dynamic RegistrationForm.
An interesting point is the line that sets the "TASK" to "Edit". This value is used by the server page to adjust the page title and form layout. When we defined the RegistrationForm, we set the default value for TASK to be "Create". When EditRegistration is called from the Welcome page, we don't have a User object yet, and so the TASK remains at "Create". When EditRegistration is called from the MainMenu page, we do have a User object, and so the TASK is set to "Edit".
BaseAction.doSaveToken
protected void doSaveToken(HttpServletRequest request) { if (log.isTraceEnabled()) { log.trace(Constants.LOG_TOKEN); } saveToken(request); }
A common problem with designing web applications is that response times can vary and users are impatient. Sometimes, people will press a submit button a second time. When this happens, the browser submits the request again, so that we now have two requests for the same thing. In the case of registering a user, if someone does press the submit button again, and their timing is bad, it could result in the system reporting that the username has already been used. (The first time the button was pressed.) In practice, this would probably never happen, but for a longer running process, like verifying a credit card transaction, it's easier for a double submit to occur.
To forestall double submits, the framework can generate a token that is embedded in the form and also kept in the session. If the value of the tokens do not compare, then we know that there has been a problem, and a form has been submitted twice or out of sequence.
The doSaveToken helper, logs the event for tracking, and then calls the framework method. Later, when we Save the registration, we will check to see if the token is valid.
After the token has been saved, Edit calls "doFindSuccess and" control flows to the Registration page.
Registration page
If you follow the "Edit your user registration profile" link from the Main Menu page, we will finally reach the heart of the MailReader application: the Registration, or "Profile", page. This page displays everything MailReader knows about you (or at least your login), while utilizing several interesting techniques.
To do double duty as the "Create" Registration page and the "Edit" Registration page, the Registation.jsp makes good use of logic tags, to make it appears as though there are two distinct pages. For example, if you are editing the form (task == "Edit"), the page inserts your username from the RegistrationForm bean. If you are new user (task == "Create"), the page creates an empty field, so you can pick your username.
Note:
Presention Logic - The Struts logic tags are a convenient way to express presentation logic within your pages. Customized pages help to prevent user error, and dynamic customization reduces the number of JSPs your application needs to maintain, among other benefits.
The page also uses logic tags to display a list of subscriptions for the given user. If the RegistrationForm has task set to "Edit", the lower part of the page that lists the subscriptions is exposed.
<logic:equal name="RegistrationForm" property="task" scope="request" value="Edit">
<bean:message key="heading.subscriptions"/>
   <bean:message key="registration.addSubscription"/>  </logic:equal>
Otherwise, the page contains just the top portion -- a blank data-entry form for creating the user's registration.
logic:iterate
Beside making the usual conditional tests, you can also use logic tags to forward control to other actions, to redirect control to another path, and to iterate over collections. The Registration page includes a good example of using the logic:iterate tag to display the user's subscriptions.
The subscriptions are stored in a hashtable object, which is in turn stored in the user object. So to display each subscription, we have to reach into the user object, and loop through the members of the subscription collection. Using the iterate tag, you can code it the way it sounds.
Using logic:iterate to list the Subscriptions
<logic:iterate name="user" property="subscriptions" id="subscription">
  <bean:write name="subscription" property="host"/> 	  <bean:write name="subscription" property="username"/> 	  <bean:write name="subscription" property="type"/> 	  <bean:write name="subscription" property="autoConnect"/> 	   <bean:message key="registration.deleteSubscription"/>   <bean:message key="registration.editSubscription"/>
 </logic:iterate>
The three parameters to the iterate tag (name, property, and id) tell it to
- name - Check this context for an attribute (e.g. object) named user,
- property - Snag the property of user named subscriptions,
- id - In the block to iterate, use subscription (singular) as the name for each member of the collection.
Next to each entry in the subscription list are links to Delete and Edit commands. These links use the same name/property/id trinity as the interator, except that the attributes are used to create a hyperlink with a single parameter. (Multiple parameters are possible too, but if the code is well-factored, one should be sufficient.)
Given a subscription to "mail.yahoo.com", the command links would translate to HTML links like these:
The Delete and Edit links for mail.yahoo.com
Delete Edit
At the foot of the Register page is a link for adding a subscription. Let's wind up the tour by following the Add link and then logging off. Like the link for creating a Registration, Add points to an "Edit" action, namely "EditSubscription".
SubscriptionAction.java
The EditSubscription link shares the Wildcard "/Edit*" mapping we saw with EditRegistration. As before, in the case of "EditSubscription", the "{1}Form" attribute maps to SubscriptionForm.
The SubscriptionAction form-bean element
<form-bean name="SubscriptionForm" extends="BaseForm"> <form-property name="autoConnect" type="java.lang.Boolean" initial="FALSE" reset="true"/> <form-property name="host" type="java.lang.String" /> <form-property name="type" type="java.lang.String" /> </form-bean>
The other DynaActionForms we've seen used only String properties. SubscriptionForm is different in that it uses a Boolean type for the "autoConnect" property. On the HTML form, the autoConnect field is represented by a checkbox, and checkboxes need to be handled differently that other controls.
Tip:
Checkboxes - The HTML checkbox is a tricky control. The problem is that, according to the W3C specification, a value is only guaranteed to be sent if the control is checked. If the control is not checked, then the control may be omitted from the request, as if it was on on the page. This can cause a problem with session-scope checkboxes. Once you set the checkbox to true, the control can't set it to false again, because if you uncheck the box, nothing is sent, and so the control stays checked.
The simple solution is to set the initial value for a checkbox control to false before the form is populated. If the checkbox is checked, it will return a value, and the checkbox will represent true. If the checkbox is unchecked, it will not return a value, and the checkbox will remain unchecked ("false").
To be sure the autoConnect checkbox is handled correctly, the SubscriptionForm initializes the property to FALSE, and enables "reset" so that before autopopulation the property is set back to FALSE.
The SubscriptionAction Edit method should look familiar, but it also has a few twists of its own.
SubscriptionAction.Edit
public ActionForward Edit( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { final String method = Constants.EDIT; doLogProcess(mapping,method); HttpSession session = request.getSession(); User user = doGetUser(session); if (user==null) return doFindLogon(mapping); // Retrieve the subscription, if there is one Subscription subscription; String host = doGet(form,HOST); boolean updating = (host!=null); if (updating) { subscription = doFindSubscription(user,host); if (subscription==null) return doFindFailure(mapping); session.setAttribute(Constants.SUBSCRIPTION_KEY, subscription); doPopulate(form,subscription); doSet(form,TASK,method); } return doFindSuccess(mapping); }
In RegistrationAction.Edit, we looked for the user object to decide if we were updating or inserting. In SubscriptionAction.Edit, the user object is required (and we trot off to the Login page if it is missing). This could happen because a session expired, or because someone bookmarked a page.
To decide if we are inserting or updating a subscription, we look to see if the host is set to the ActionForm. If it is an update, we fetch the Subscription from the database.
SubscriptionAction.doFindSubscription
private Subscription doFindSubscription(User user, String host) { Subscription subscription; try { subscription = user.findSubscription(host); } catch (NullPointerException e) { subscription = null; } if ((subscription == null) && (log.isTraceEnabled())) { log.trace( " No subscription for user " + user.getUsername() + " and host " + host); } return subscription; }
If we can't find the subscription, we use doFindFailure to forward to the Failure result (Error.jsp).
BaseAction.doFindFailure
protected ActionForward doFindFailure (ActionMapping mapping) { if (log.isTraceEnabled()) { log.trace(Constants.LOG_FAILURE); } return (mapping.findForward(Constants.FAILURE)); }
In the normal course, the subscription should always be found, since we selected the host from a system-generated list. If the subscription is not found, it would be because the database disappeared or the request is being spoofed.
Like the RegisterAction, the doPopulate method transfers data from the form to the domain object. In this case, a Subscription object.
SubscriptionAction.doPopulate
private void doPopulate(ActionForm form, Subscription subscription) throws ServletException { final String title = Constants.EDIT; if (log.isTraceEnabled()) { log.trace(Constants.LOG_POPULATE_FORM + subscription.getHost()); } try { PropertyUtils.copyProperties(form, subscription); doSet(form,TASK,title); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t == null) t = e; log.error(LOG_SUBSCRIPTION_POPULATE, t); throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t); } catch (Throwable t) { log.error(LOG_SUBSCRIPTION_POPULATE, t); throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t); } }
Most of the code in "doPopulate" is window dressing for the call to PropertyUtils.copyProperties, which does the heavy lifting.
But before turning to our final JSP, a word about our database model ...
User.java and Subscription.java
If you're used to working with relational databases, the links between the user and subscription objects may be confusing. A conventional relational database would create two distinct tables, one for the users and another for the subscriptions, and link them together with a user ID. The MailReader application implements a different model, a hierarchical database. Here a "table" of subscriptions is stored within each user object, something like the way a filing system stores documents within folders.
Development teams often use frameworks like Cayenne to map a relational database to a hierarchy of objects, like the one used by MailReader. For simplicity, the MailReader doesn't use a conventional database, but saves its data as an XML file. While the MailReader is running, the database is kept in main memory, and written to back to disk when changed.
In addition to the usual getters and setters, the user object also has two methods for working with subscription objects. The findSubscription method takes a hostname and returns the subscription object for that host. The getSubscriptions method returns an array of all the subscriptions for the user (ready-made for the iterate tag!). Besides the fields needed to manage the SubscriptionForm data, the object also maintains a runtime link to its own user object.
To create a new subscription, SubscriptionAction.java simply creates a new subscription object, and sets its user to the object found in the request, and then forwards control to its input form, Subscription.jsp.
Subscription.jsp
Saving the best for last, Subscription.jsp utilizes two interesting Struts custom form tags, "html:options" and "html:checkbox".
In Registration.jsp, the Struts iteration tag was used to write a list of subscriptions. Another place where iterations and collections are handy is the option list for a HTML select tag. Since this is such a common situation, Struts offers a html:options (plural) tag that can take an array of objects as a parameter. The tag then iterates over the members of the array (beans) to place each one inside an standard option tag. So given a block like

The tag outputs a block like
<select name="type"> <option value="imap" selected>IMAP Protocol</option> <option value="pop3">POP3 Protocol</option> </select>
Here, one collection contained both the labels and the values, from properties of the same name. Options can also use a second array for the labels, if they do not match the values. Options can use a Collection, Iterator, or Map for the source of the list.
Unlike other data, the serverTypes array is not fetched from the database. Instead, it is loaded by a Struts plugin. The DigestingPlugin parses an XML document using a given set of Digester rules. The MailReader uses a set of rules for "LabelValueBeans" to create a list of server types.
Tip:
LabelValueBeans - Many developers find the LabelValueBeans useful, so the class is available in the Struts Action distribution as [org.apache.struts.util.LabelValueBean].
The plugin stores the list is stored in application scope. Since the Struts custom tags, like standard JSP tags, search the scopes in succession, the tag finds the list in application scope and uses it to write out the options.
SubscriptionForm.java
Back in Subscription.jsp, we have one more block to cover. Although the same basic form can be used to created, edit, or delete a subscription, people might expect the buttons to be labeled differently in each case. Like the Registration page, the Subscription page handles customization by using a logic tag to output a different set of buttons for each case. Changing buttons doesn't really change the way the Subscription page works, but customizing the buttons does make things less confusing for the user.
<logic:equal name="SubscriptionForm" property="task" scope="request" value="Create">  <bean:message key="button.save"/>
 </logic:equal>In the case of a request to delete a subscription, the submit button is labeled "Confirm", since this view is meant to give the user a last chance to cancel, before sending that task along to SaveSubscriptionAction.java.
The actual task property is placed into the form as a hidden field, and SaveSubscriptionAction uses that property to execute the appropriate task.
SubscriptionAction.java
Our final stop has the job of finishing what SubscriptionAction.Edit started. After the usual logic and error checking, The SubscriptionAction.Save method either deletes or updates the subscription object being handled by this request, and cleans up the bean, just to be tidy. By now, you should be very comfortable reading through the source on your own, to pickup the finer points.
SubscriptionAction.Save
public ActionForward Save( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { final String method = Constants.SAVE; doLogProcess(mapping,method); User user = doGetUser(request); if (user == null) { return doFindLogon(mapping); } HttpSession session = request.getSession(); if (isCancelled(request)) { doCancel(session,method,Constants.SUBSCRIPTION_KEY); return doFindSuccess(mapping); } String action = doGet(form,TASK); Subscription subscription = doGetSubscription(request); boolean isDelete = action.equals(Constants.DELETE); if (isDelete) { return doRemoveSubscription (mapping,session,user,subscription); } if (subscription==null) { subscription = user.createSubscription(doGet(form,HOST)); session.setAttribute(Constants.SUBSCRIPTION_KEY,subscription); } doPopulate(subscription,form); doSaveUser(user); session.removeAttribute(Constants.SUBSCRIPTION_KEY); return doFindSuccess(mapping); }
This concludes our tour. To review, you may wish to trace the path a new user takes when they register with the application for the first time. You should also read over each of the .java and JSP files carefully, since we only covered the high points here.
Review
- Struts uses a single controller servlet to route HTTP requests.
- The requests are routed to action objects according to path (or URI).
- Each request is handled as a separate thread
- There is only one object for each action (URI), so your action objects must be multi-thread safe.
- The configuration of action objects are loaded from a XML resource file, rather than hardcoded.
- Action objects can respond to the request, or ask the controller to forward the request to another object or to another page, such as an input form.
- A library of custom tags works with the rest of the framework to enhance use of JavaServer Pages.
- The Struts form tag can work closely with an action objects via a Struts ActionFormBean to retain the state of a data-entry form, and validate the data entered.
- ActionForm beans can be automatically created by the JSP form or controller servlet.
- Struts supports a message resource for loading constants strings. Alternate message resources can be provided to internationalize an application.


The aim of the genesis tests is to provide a baseline to test genesis-state initialization and test if the proposed genesis-validity conditions are working.
There are two handlers, documented individually:
validity
: Tests if a genesis state is valid, i.e. if it counts as trigger to launch.initialization
: Tests the initialization of a genesis state based on Eth1 data.SSZ SimpleSerialize


--- ---
Prof. Govindan Rangarajan, Indian Institute of Science, India
Prof. Vinod Sharma, Indian Institute of Science, India


{% extends 'html/base.html' %} {% block title %}
The good idea is to return to selfmailbot and try again. Feel free to contact us at<EMAIL_ADDRESS>for any questions.


Screen Play presents new collaborative and solo work by artists Katy Albert and Emily Eddy.
Opens October 11th, 6-9 p.m.
October 11 - November 9th
Screen Play presents new collaborative and solo work by artists Katy Albert and Emily Eddy.
Opens October 11th, 6-9 p.m.
October 11 - November 9th


{% extends "global/Page.html" %} {% load otree static %} {% block title %} Prediction Tasks and "Rumours" {% endblock %} {% block content %}
Everyone in your group will face the same prediction task. At the beginning of each session, you will receive a clear description of the prediction tasks-- including context of the prediction task, possible outcomes etc. In addition, each of you will receive a rumour about the outcome of the event. Each prediction task will resemble the one given in example below. The outcome will be determined by computer randomly before the first character places the bet. Of course, the outcome will not be revealed until the end of the experiment.
You may also observe decisions made by other players in your group before you submit your predictions. In addition, you will receive information relevant to the prediction task, which is called a "rumour". This resembles "rumours" in our daily life, in the sense that it contains relevant information about the outcome, but they are not always correct about the outcomes. For each piece of rumour, you will be told exactly the generating process, from which you can infer relevant information and use that to your advantage. Remember that others will also receive similar rumours as yours; if you pay attention to other players' decisions, you may be able to infer information useful to help you make better predictions. Lastly, we want to stress that rumours in this experiment are not meant to be deceptive or inaccurate in this experiment.
{% next_button %}(If the image is not loading properly, please right click on the image icon, and select "Open Image in New Tab".)
{% endblock %}


Edit mode
New connection
Export
Import
Select where to add the point
Add Item
Name
*
Description
State
*
Planned
Work in progress
Shipped
Position
*
Left
Right
Center
Reference
Type
Story
Epic
Defect


| Documentation Contents |
jhat [ options ] <heap-dump-file>
- options
- Options, if used, should follow immediately after the command name.
- heap-dump-file
- Java binary heap dump file to be browsed. For a dump file that contains multiple heap dumps, you may specify which dump in the file by appending "#<number> to the file name, i.e. "foo.hprof#3".
DESCRIPTION
The jhat command parses a java heap dump file and launches a webserver. jhat enables you to browse heap dumps using your favorite webbrowser. jhat supports pre-designed queries (such as 'show all instances of a known class "Foo"') as well as OQL (Object Query Language) - a SQL-like query language to query heap dumps. Help on OQL is available from the OQL help page shown by jhat. With the default port, OQL help is available at http://localhost:7000/oqlhelp/
There are several ways to generate a java heap dump:
- Use jmap -dump option to obtain a heap dump at runtime;
- Use jconsole option to obtain a heap dump via HotSpotDiagnosticMXBean at runtime;
- Heap dump will be generated when OutOfMemoryError is thrown by specifying -XX:+HeapDumpOnOutOfMemoryError VM option;
- Use hprof.
NOTE: This tool is experimental and may not be available in future versions of the JDK.
OPTIONS
- -stack false/true
- Turn off tracking object allocation call stack. Note that if allocation site information is not available in the heap dump, you have to set this flag to false. Default is true.
- -refs false/true
- Turn off tracking of references to objects. Default is true. By default, back pointers (objects pointing to a given object a.k.a referrers or in-coming references) are calculated for all objects in the heap.
- -port port-number
- Set the port for the jhat's HTTP server. Default is 7000.
- -exclude exclude-file
- Specify a file that lists data members that should be excluded from the "reachable objects" query. For example, if the file lists java.lang.String.value, then, whenever list of objects reachable from a specific object "o" are calculated, reference paths involving java.lang.String.value field will not considered.
- -baseline baseline-dump-file
- Specify a baseline heap dump. Objects in both heap dumps with the same object ID will be marked as not being "new". Other objects will be marked as "new". This is useful while comparing two different heap dumps.
- -debug int
- Set debug level for this tool. 0 means no debug output. Set higher values for more verbose modes.
- -version
- Report version number and exit.
- -h
- Output help message and exit.
- -help
- Output help message and exit.
- -J<flag>
- Pass <flag> to the Java virtual machine on which jhat is run. For example, -J-Xmx512m to use a maximum heap size of 512MB.
SEE ALSO
Copyright © 1993, 2011, Oracle and/or its affiliates. All rights reserved.
Please send comments using this Feedback page.
Java Technology


#import <ATPreferencePane.h>
Detailed Description
The main controller class for the preference pane. Handles all of the logic.
Member Function Documentation
| - (void) addToLoginItems: |
|
(LSSharedFileListRef) |
theLoginItemsRefs |
| forPath: |
|
(CFURLRef) |
thePath |
|
|
| |
Add the application referenced by thePath to the list of user's login items.
- Parameters:
-
| [in] | theLginItemsRefs | The list of user's login items. |
| [in] | thePath | The URL to the application to be added. |
- Todo:
- Modify this method, or make a new one, that gets the login items on its own (without a parameter).
| - (BOOL) appTrapIsRunning |
|
|
|
Returns a BOOL indicating whether AppTrap is running or not.
- Returns:
- the BOOL indicating whether AppTrap is running.
| - (IBAction) automaticallyCheckForUpdate: |
|
(id) |
sender |
|
Enable or disable automatic update checking, depending on the sender's state. Called by a checkbox.
- Parameters:
-
| [in] | sender | The control that invoked this method (likely a checkbox). |
| - (void) checkBackgroundProcessVersion |
|
|
|
Send a notification to the background process asking for its version number.
| - (void) checkBackgroundProcessVersion: |
|
(NSNotification*) |
notification |
|
Method called by the NSDistributedNotificationCenter on behalf of the background process. Checks the background process version in the userInfo dictionary in notification and opens an appropriate alert sheet if the background process version is different from the preference pane version.
- Parameters:
-
| [in] | notification | The NSNotification that invoked this method. |
| - (IBAction) checkForUpdate: |
|
(id) |
sender |
|
Check if there is an update. Called by a button.
- Parameters:
-
| [in] | sender | The control that invoked this method (likely a button). |
| - (BOOL) inLoginItems: |
|
(LSSharedFileListRef) |
theLoginItemsRefs |
| forPath: |
|
(CFURLRef) |
thePath |
|
|
| |
Check to see if the application referenced by thePath is in the user's list of login items.
- Parameters:
-
| [in] | theLoginItemsRefs | The list of the user's login items. |
| [in] | thePath | The URL to the application in question. |
- Returns:
- a BOOL indicating whether the application referenced by thePath is in the user's list of login items.
- Todo:
- Modify this method, or make a new one, that gets the login items on its own (without a parameter).
Launch the AppTrap background process.
| - (void) removeFromLoginItems: |
|
(LSSharedFileListRef) |
theLoginItemsRefs |
| forPath: |
|
(CFURLRef) |
thePath |
|
|
| |
Remove the application referenced by thePath from the list of user's login items.
- Parameters:
-
| [in] | theLoginItemsRefs | The list of user's login items. |
| [in] | thePath | The URL to the application to be added to the list of login items. |
- Todo:
- Modify this method, or make a new one, that gets the login items on its own (without a parameter).
| - (IBAction) startOnLogin: |
|
(id) |
sender |
|
Add or remove the AppTrap background process from the user's login items, depending on the state of sender. Called by a checkbox.
- Parameters:
-
| [in] | sender | The control that invoked this method (likely a checkbox). |
| - (IBAction) startStopAppTrap: |
|
(id) |
sender |
|
Start or stop the AppTrap background process. Called by a button.
- Parameters:
-
| [in] | sender | The control that invoked this method (likely a button). |
| - (void) terminateAppTrap |
|
|
|
Terminate the AppTrap background process. Sends a notification that the background process receives.
Check to see if AppTrap is running and update the user interface accordingly.
| - (IBAction) visitWebsite: |
|
(id) |
sender |
|
Open the AppTrap website in the user's default browser. Called by a button.
- Parameters:
-
| [in] | sender | The control that invoked this method (likely a checkbox). |
The documentation for this class was generated from the following files:


|
keigeki
1.0.0
傾撃
|
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include "kazmath/utility.h"
#include "kazmath/vec3.h"
#include "kazmath/mat3.h"
#include "kazmath/quaternion.h"
Functions | |
| kmMat3 *const | kmMat3Fill (kmMat3 *pOut, const kmScalar *pMat) |
| kmMat3 *const | kmMat3Identity (kmMat3 *pOut) |
| const kmScalar | kmMat3Determinant (const kmMat3 *pIn) |
| kmMat3 *const | kmMat3Adjugate (kmMat3 *pOut, const kmMat3 *pIn) |
| kmMat3 *const | kmMat3Inverse (kmMat3 *pOut, const kmScalar pDeterminate, const kmMat3 *pM) |
| const int | kmMat3IsIdentity (const kmMat3 *pIn) |
| kmMat3 *const | kmMat3Transpose (kmMat3 *pOut, const kmMat3 *pIn) |
| kmMat3 *const | kmMat3Multiply (kmMat3 *pOut, const kmMat3 *pM1, const kmMat3 *pM2) |
| kmMat3 *const | kmMat3ScalarMultiply (kmMat3 *pOut, const kmMat3 *pM, const kmScalar pFactor) |
| kmMat3 *const | kmMat3Assign (kmMat3 *pOut, const kmMat3 *pIn) |
| const int | kmMat3AreEqual (const kmMat3 *pMat1, const kmMat3 *pMat2) |
| kmMat3 *const | kmMat3Rotation (kmMat3 *pOut, const float radians) |
| kmMat3 *const | kmMat3Scaling (kmMat3 *pOut, const kmScalar x, const kmScalar y) |
| kmMat3 *const | kmMat3Translation (kmMat3 *pOut, const kmScalar x, const kmScalar y) |
| kmMat3 *const | kmMat3RotationQuaternion (kmMat3 *pOut, const kmQuaternion *pIn) |
| kmMat3 *const | kmMat3RotationAxisAngle (kmMat3 *pOut, const struct kmVec3 *axis, kmScalar radians) |
| kmVec3 *const | kmMat3RotationToAxisAngle (kmVec3 *pAxis, kmScalar *radians, const kmMat3 *pIn) |
| kmMat3 *const | kmMat3RotationX (kmMat3 *pOut, const float radians) |
| kmMat3 *const | kmMat3RotationY (kmMat3 *pOut, const float radians) |
| kmMat3 *const | kmMat3RotationZ (kmMat3 *pOut, const float radians) |
Returns true if the 2 matrices are equal (approximately)
| const int kmMat3IsIdentity | ( | const kmMat3 * | pIn | ) |
Returns true if pIn is an identity matrix
| kmMat3* const kmMat3RotationAxisAngle | ( | kmMat3 * | pOut, |
| const struct kmVec3 * | axis, | ||
| kmScalar | radians | ||
| ) |
| kmMat3* const kmMat3RotationQuaternion | ( | kmMat3 * | pOut, |
| const kmQuaternion * | pIn | ||
| ) |
|
read |
Builds an X-axis rotation matrix and stores it in pOut, returns pOut
Builds a rotation matrix using the rotation around the Y-axis The result is stored in pOut, pOut is returned.
Builds a rotation matrix around the Z-axis. The resulting matrix is stored in pOut. pOut is returned.
Builds a scaling matrix


University to make public apology to Aboriginal people for past 'wrongdoings'
The Vice-Chancellor of the University of Tasmania says the institution will 'apologise' for the 'grave consequences' Aboriginal people have suffered since 1803.
by Douglas SmithThe University of Tasmania will make a public apology next month for its role in past "wrongdoings" against the palawa kani people.
The university's Vice-Chancellor Rufus Black has sent an email out to staff that said the apology was "the right and necessary thing to do" and was a step towards "true healing" with the Aboriginal people of Tasmania, the Advocate Tasmania reported on Sunday.
Local Aboriginal leader, Michael Mansell said the apology was "sincere" and "accepted in that spirit."
Tasmanian Aboriginal leader, Michael Mansell.
Mr Mansell described apologies for historic wrongdoing as not being "admissions of guilt", but instead served as examples that showed how people today were prepared to take responsibility for the consequences of the past.
"These include invasion, frontier war, massacres, incarceration at Wybalenna and Putalina/Oyster Cove, State-sanctioned disinterment and collection of Aboriginal human remains, the denial of human rights and even of the Tasmanian Aboriginal community's very existence," said Prof Black.
"There is no single measure or dimension that can describe or start to capture the wrong that has been done in this time or the magnitude of that wrongdoing.
The apology will be recorded on a plaque and written in both palawa kani and English.


and the influenza for vaccine that with []. can are viral from The have design immune data protein Influenza approaches virus computational universal been conserved epitopes {background models potential these T-cell [,]. ancestral has sequence used epitope against prediction margin sequences which Vaccine antigens responses this {border-style host information not phylogenetic px;} viruses #ffffff;} pathogen selection vaccines This antibody different evolutionary more clinical consensus may multiple protection design. improve modeling strains structural These based development immunity into learning seasonal all broadly completed cross-reactive experimental genetic including novel proteins where Computational [,,]. analysis antigenic epitope-based evolution generated new pandemic population tools Biol. [], approach broad current disease efforts functional global human identify make response sampling Design However, NCT Universal circulating developed full generate machine model predict profile protective reconstruction sharing structure B-cell across amino antibodies between candidates components computationally domains each elicit evidence high highly incorporate provide px; repertoire stalk surface within {font-family Acad. Figure For NCT, Natl. Sci. Virus With available binding cell common coverage efficacy epidemiological evolvability example, font-size important limited molecular needed online: phase predictions samples studies subtypes surveillance system through were will (Figure .collab: But Evolution Evolutionary Furthermore, J.B.; MHC Phylogenetic T-cells USA./pnas. Vaccines availability being cells cellular conformational could critical currently develop double; during factors function functions head immunogenicity its major methods most optimized other phylodynamic reactive review site some technologies three was zoonotic ... Approaches Broadly Clinical Epitope February Flu-v Hemagglutinin Immunomics Infect. ONEe./journal.pone. Opin. Pre-clinical Seasonal X.Q. account advanced affinity after algorithms also animal antigen applied approach. biological border-color border-width both but challenges characteristics collected computed diversity domain drift due dynamics ecological gene genomic group hemagglutinin hosts humoral include increased infection integrate integrated low mutations natural peptides populations prevent promising research sequencing several should solid; specific strain study such they trials under understanding vaccine. when would {font-style {font-weight Antibodies COBRA Centers Comput. Experimental FP-. Global Human Machine Model Mol. Optimized Reactive Rev. Table accurate accurately acid al. among avian better bias bold broadly-reactive cannot capture challenge complete complex consensus-based courier; datasets derived design, designed developing diverse durable effectively effects em; emerging estimation evaluate evolutionarily experiments explore facilitate found framework genome geographical help heterogeneity high-throughput history how identification immunological immunomics impacts infectious inference inhibition input integration large like main many mapping mutational neutralizing one outbreaks overcome previous production pt;} quantify rapid records represent scaffold sources still strains, subtype swine-origin tested than towards traditional trial understand unpublished using valuable variability virus. viruses. well while


Popular Areas in mtd ranch king clutch adjustment
MTD Electric PTO Clutch
Not doing so could cause Electric Clutch Premature Failure which will void warranty. Warner . MTD 42" and 46" Ranch King, Yardman and Yard Machine .
http://www.psep.biz/store/mtd_electric_pto_clutch.htm
MTD riding lawn mower - YouTube
Apr 6, 2008 . A "Ranch King" by MTD, if I'm not mistaken. . tractor and i need help on how? to change the belts on it idont know how to do it with that clutch so .
http://www.youtube.com/watch?v=b0EWV2cNZNw
I installed a new starter solenoid in my ranch King - FixYa
mtd ranch king lawn mower drive belt-how to put on the belt. dmill1284; Jul 11, 2009 . Unsolved Riding Mowers & Garden Tractors Problems .
http://www.fixya.com/support/t9391470-installed_new_starter
MTD Transmatic Questions - Tractors Forum - GardenWeb
Have a vintage Ranch King (MTD 139.652 F205) that I like to keep in service. . with the classic sensitivity to pulling back on the clutch/brake pedal. . have been the correct replacement, but the blades never completely lose .
http://forums2.gardenweb.com/forums/load/tractor/msg0509134413624.html
I need a belt diagram for a ranch king king plus - FixYa
mtd ranch king lawn mower drive belt-how to put on the belt. dmill1284; Jul 11 . Unsolved Mtd Riding Mowers & Garden Tractors Problems .
http://www.fixya.com/support/t2904158-need_belt_diagram_ranch_king_king_plus
Riding Lawn Mowers - How To Information | eHow.com
Replacement is straightforward, as is removal and replacement of the axle . The electric clutch on your riding mower is controlled by the PTO engage/disengage switch. . The Ranch King, manufactured by MTD, is a basic riding lawn tractor .
http://www.ehow.com/riding-lawn-mowers/


API for a session management used in the WSGI Adaptor
This class provides in-process session management using anydbm.
Creates a session client using the the file dbFileName for session storage. The cookieName contains the name of the cookie that will be sent to the client to identify the session. The sessionLifeSpan is in seconds, and defaults to one hour.
Used by the WSGI Adaptor to retrieve the session for a client in order to pass it to the application through the Request object.
Used by the WSGI Adaptor to save the contents of a session for future retrieval.
Un-used. Tells the client that no further sessions will be requested or saved.
Connects to a SessionServer listening on the Unix domain socket at the socketLocation. All other parameters and methods are the same as for LocalSessionClient.


New Post
The first post.⌗
First post for using, playing around and possibly replacing my site using a site generator.
- Why: less server services running especially sql and PHP is a happier server
- Less: load on the server currently the highest usage are from php, sql
- Able to install OpenBSD and use it’s internal basic httpd
- Static files load fast just like they did in the early 90’s


Getting Started with iOS
Video Tutorials:
1. Requirements
- Intel-based computer with Mac OS X Snow Leopard (10.6)
- Necessary for Installing on Device:
- An Apple iOS device (iPhone, iPad, iPod Touch)
- iOS developer certification
2. Install SDK + PhoneGap
- Download and install Xcode from Apple Developer Portal (Membership required)
- Donwload the latest copy of PhoneGap and extract its contents. We will be working with the Android directory.
3. Setup New Project
- Launch Xcode, then under the File menu select New and then New Project...
-
Select PhoneGap-based Application from the list of templates
-
Select the Next button, Fill in the "Product Name" & "Company Identifier" for your app
Choose a directory to store your app
- You should see your project in Xcode 4 now. Press the Run button in the top left corner. Your build should succeed and launch in the simulator
- You should see a error in your simulator informing you index.html was not found
- To fix this, we need to copy the www directory into the project. Right click on the project in the left navigation window and click show in finder
- In Finder, you should see the www directory beside your project
-
Next step is IMPORTANT! Drag the www folder into Xcode 4. You can't just drag the www folder into your app's folder. It needs to be dragged into Xcode 4!! In my case I would drag it and drop it on HiWorld shown below.
- After you drag, you should see a prompt with a few options. Make sure to select Create folder references for any added folders. Click Finish
4. Hello World
Open the folder named www and type
Hello World

after the
tag in index.html. You can also add any associated Javascript and CSS files there as well.
5A. Deploy to Simulator
- Make sure to change the Active SDK in the top left menu to Simulator+version#.
- Hit Run in your project window header.
5B. Deploy to Device
- Open [AppName]-Info.plist and change BundleIdentifier to the identifier provided by Apple. If you have a developer license, you can access and run the Assistant at here and register your App.
- Make sure to change the Active SDK in the top left menu to Device+version#.
-
Hit Run in your project window header.
Done!
You can also checkout more detailed version of this guide here.


-
v Príomh Ó hÚigínn
My Blog. Just because you can blog, it doesn't mean you should.
blog.higg.im
-
Δ Unicode Tools
Make your text more fun / interesting. Be creative with Unicode. ASCII is officially dead.
unicod.es
-
☠ The Github Pirates
The Github Pirates is a constantly updated resource for those interested in HTML5, CSS3, and JavaScript.
codepirat.es
-
♫ MJEX Fansite
I like the Hip-Hop group MJEX a lot, so I created this site for them. (Messiah J & the Expert)
code.higg.im
-
' Twitter Stream
A real-time aggregator of Twitter posts. Discontinued.
open.higg.im
projects:
-
k iwantaneff.in / toolset
A growing collection of handy online web development tools.
iwantaneff.in/toolset
-
T Handpicked jQuery
Collection of curated jQuery plugins, hosted on a CDN
jque.re
-
l Devlinks
Frontend Links is a collection of links related to web development.
devlinks.co.uk
- c
-
= Social Media
Obligatory badges and share buttons


The Tree
I was a child, afraid of darkness and strangers
What lingered in my closet, irrational dangers
Snuggled between emerald leaves and autum’s residue
I climbed above branches as seasons waved adieu
Carved initials into treebark with wood-chipped fingers
The scent of daydreams washed with coppice still lingers
Felt warmth on my shoulder when moonlight teased the tree
Silver beams peeked through knotholes just to visit me
But now I’m running in empty highways
Finding bits of me in dead-ends of this maze
Stuck in a metro forever leading me
Down the path of some distant memory
Troubled sleeping in the lonely, roaring subway
Misled by blinding neon signs stuck in a pathway
Skyscrapers peering down, leering at what they see
Stoplights turning red when they’re ahead of me
I return to the tranquil, moss-frosted grove
As a native, homegrown, to my treasure trove
To find dead branches on thin, dusty ground
Aesthetic and lawless, now cracked and browned
Searching for intials carved into treebranches crazily
Only to find a firmly-tied noose hanging lazily
Harsh rope cutting against a poor someone’s throat
A knot staring back at me, it almost seems to gloat
Yet something stops me from seeing the dead face
For I remember a child in a wonderful place
Afraid of darkness and strangers
What lingered in a closet, irrational dangers
Without seeing, without feeling, I know it’s she
Simply a dusty and forgotten remnant of me
Now I’m afraid of setting off for something new
And returning a stranger to what I thought I knew
If I could come back to emerald leaves and autum’s residue
And climb over branches as seasons wave adieu
If I could come back to silver beams visiting me
If I could come back to the tree


A beginners guide to the Unix and Linux operating system. Eight simple tutorials which cover the basics of UNIX / Linux commands.
Introduction to the UNIX Operating System
- What is UNIX?
- Files and processes
- The Directory Structure
- Starting an UNIX terminal
Tutorial One
- Listing files and directories
- Making Directories
- Changing to a different Directory
- The directories . and ..
- Pathnames
- More about home directories and pathnames
Tutorial Two
- Copying Files
- Moving Files
- Removing Files and directories
- Displaying the contents of a file on the screen
- Searching the contents of a file
Tutorial Three
- Redirection
- Redirecting the Output
- Redirecting the Input
- Pipes
Tutorial Four
- Wildcards
- Filename Conventions
- Getting Help
Tutorial Five
- File system security (access rights)
- Changing access rights
- Processes and Jobs
- Listing suspended and background processes
- Killing a process
Tutorial Six
- Other Useful UNIX commands
Tutorial Seven
- Compiling UNIX software packages
- Download source code
- Extracting source code
- Configuring and creating the Makefile
- Building the package
- Running the software
- Stripping unnecessary code
Tutorial Eight
- UNIX variables
- Environment variables
- Shell variables
- Using and setting variables
Recommended UNIX and Linux books
- If you wish to continue learning Unix, here is a list of good Unix and Linux books, ranging from beginners to advanced.
Download
- This tutorial is available for download so you can work offline. You can also copy and modify it for your own site. Please read the terms and conditions.
Useful Links
- Links to other UNIX resources.
This tutorial is licensed under a Creative Commons License.
<EMAIL_ADDRESS>19 October 2001


EXPLORE THE TABLES
Gordon Ramsay Bar & Grill will create an inviting atmosphere for all-day dining, from breakfast and lunch through afternoon tea to evening dinners and cocktail hours. There will also be the opportunity for private dining. With floor-to-ceiling windows looking out over the Sunway Lagoon, the views will be spectacular. Diners can select from an impressive menu, specialising in premium ingredients and exceptional flavours including the prime cuts of the finest meat, locally sourced and dry-aged in-house, as well as the very best elements from Gordon Ramsay’s world-famous signature dishes
Nobu Restaurant, is the world’s most recognized Japanese restaurant known for its innovative new style cuisine with an extensive menu of inventive dishes and bold cocktails.  Malaysian street food stall serving up food that Julie's mother taught her to make. Well-known from street food festivals and markets like the Big Feed, Feast End Street Food Festival and Ross Street Market, or from fixtures at Gordon Lane and Buchanan Galleries.


MURDER AT 1600 A film review by Andrew Hicks Copyright 1997 Andrew Hicks
(1997) *1/2 (out of four)
There's only one presidential election every four years, but it seems like every few months we get another presidential conspiracy movie painted as _the_ thriller of the year. In 1997, we've had ABSOLUTE POWER, AIR FORCE ONE, SHADOW CONSPIRACY and MURDER AT 1600. This one is about as lame duck as old Gerald Ford, trying to bring us a complex plot of cover-up and intrigue but copping out over and over again with rehashes of action flick standbys.
Here's what happens this time. It's night at the White House.  The next day she's dead and hotshot detective Wesley Snipes is called in. How do we know he's a hotshot? We've seen the traditional action flick opener -- the clever hostage negotiation scene. It's not so clever this time, consisting of Snipes disarming a suicidal ex-government employee holding a gun to his head in the middle of the street.
Snipes is off to the White House, where he finds the Secret Service head (the shiny bald head of Daniel Benzali) won't cooperate with him at all. In fact, if not for the intervention of National Security Adviser Alan Alda, Snipes wouldn't have been allowed in the White House at all. Alda helps Snipes out further, assigning a sexy Secret Service agent (Diane Lane) to act as his liaison... a very dangerous liaison. Well, not really, I just wanted to say that.
Almost immediately, a suspect is found, an eccentric night janitor seen flirting with the deceased on one of the security videos. Snipes doesn't buy it, and launches into an independent investigation of his own, one that reveals planted evidence and romantic involvement by the president's son. Snipes' partner, an always- wisecracking Dennis Miller, calls him up every once in awhile with more news and Lane, who at first doesn't believe Snipes, eventually and predictably comes around, and risks her ass to break into Social Security storage and break out some classified information.
For the first hour or so, MURDER AT 1600 looks like it could be going somewhere interesting. Sure, we have to sit through the lame opening sequence and plenty more lame scenes after that, but the whole murder in the White House thing makes for an interesting premise that is never quite delivered upon. Snipes and Lane don't make for a bad action team, but with nothing to work with, they're just cogs in the bad movie machine. Dennis Miller might as well not even be in the movie; they waste his talents more in MURDER AT 1600 than they did in BORDELLO OF BLOOD, and that's saying a lot.
When you get to the last half-hour, the movie has descended metaphorically and literally into a wet sewer, busting out the old break-into-the-building underground climax. And when they finally reveal who killed the woman and why, you'll wish you never sat through this movie at all. The "1600" in the movie's title doesn't represent an address, it represents the number of satisfied customers worldwide.
--
Visit the Andrew Hicks: Movie Critic at LARGE homepage at http://www.missouri.edu/~c667778/movies.html
Serving The World For Nearly 1/25th of a Century!
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Lori Loughlin pleads not guilty to new charges in college admissions scandal
by Bashiera Parker (@bparks_)Cape Town – Lori Loughlin pleaded not guilty to new charges in the college admissions scandal on Tuesday and waived her right to appear in court over the allegations, reports NBC.
Lawyers for the Full House actress and her husband, fashion designer Mossimo Giannulli, submitted their pleas for "conspiracy to commit federal program bribery", according to People. This is on top of accusations that the couple allegedly paid $500 000 to admissions consultant and mastermind of the scandal, William "Rick" Singer, to help falsify that Loughlin and Giannulli's daughters were recruits for sports they hardly played to get them special admission consideration.
According to Vanity Fair's explainer, the couple could get a significantly longer sentence than Felicity Huffman, who pleaded guilty and had fewer indictments as well – the Desperate Housewives actress served her 14-day sentence in October and now reportedly plans on spending time helping female inmates after seeing the "harsh" conditions of those women.
Lori Loughlin may not be as lucky due to their plea and the nature of their case.
The actress and her husband could get a minimum of two to three years in prison if found guilty legal analyst, Dan Abrams, told Good Morning America.
Compiled by Bashiera Parker ( Channel24, NBC , Vanity Fair , Good Morning America , Page Six )
(Photo: Getty Images)