Tech City Systems
Use the following image to get design ideas for Cattrax-Web.

Tech City Systems
haXe (pronounced as hex) is an open source programming language which can target many programs including Flash. This means you can compile a haXe program to a .swf Flash animation. haXe is compatible with Flash Players 6 to 10, with either "old" Flash 8 API or newest AS3/Flash9+ API. haXe offers very good performance and language features to develop Flash content.

Here using haXe I'll show how to create a Flash animation which can be used as a website header. The animation shows the earth rotating in the window of an observation deck of a futuristic spacecraft. First download haXe. For a brief introduction to using haXe to creat Flash animations you can also look at the article Getting started with haXe/Flash at the haXe website.



For my example create the class ObservationDeck in the text file observationDeck.hx.

File observationDeck.hx:
import flash.Lib;
import flash.display.Loader;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.events.IOErrorEvent;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.geom.Matrix;
      class ObservationDeck
      {
      		public var loaderEarth:Loader;
      		public var bitmapEarth:Bitmap;
      		public var loaderForeground:Loader;
      		public var bitmapForground:Bitmap;
		public var matrix:Matrix;
		public var angle:Float;
		public var bgShape:Sprite;
		public var defaultBGColor:Int;
		
	      static function main()
      		{
      			new ObservationDeck();
      		}
      		public function new()
      		{      		 
      			exemple2();
      		} 
      		public function exemple2()
      		{
			defaultBGColor = 0x000000;
      			loaderEarth = new Loader();
      			loaderForeground = new Loader();
			matrix = new Matrix();
			matrix.scale(2.0, 2.0);
			matrix.translate(-150, -1775);
			angle= 0.02;
			
      			loaderEarth.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, displayError);
      			loaderEarth.contentLoaderInfo.addEventListener(Event.COMPLETE, finished);
      			loaderEarth.load(new URLRequest('earth1Small.jpg'));    
      			loaderForeground.load(new URLRequest('foregroundObservationDeck.png'));    
			
			bgShape = new Sprite();
			bgShape.graphics.beginFill(defaultBGColor);
			bgShape.graphics.drawRect(0,0,1523, 175);

      		}
      		public function displayError(e:IOErrorEvent)
      		{
      			trace("An error occured.");
      		}
      		public function finished(e:Event)
      		{			
			bitmapEarth= new Bitmap(cast(loaderEarth.content, Bitmap).bitmapData);
			bitmapEarth.smoothing = true;
			Lib.current.addChild(bgShape);
			Lib.current.addChild(bitmapEarth);
			Lib.current.addChild(loaderForeground);
			
			bitmapEarth.addEventListener(Event.ENTER_FRAME,moveMe);
     		}
      		public function progress(e:ProgressEvent)
      		{
      			trace(Std.int(e.currentTarget.bytesLoaded/e.currentTarget.bytesTotal)*100+" %");
      		}
      		public function moveMe(evt:Event)
      		{
			matrix.translate(-850, 775);
			matrix.rotate(angle * (3.14 / 180.));
			matrix.translate(850, -775);
			
			evt.target.transform.matrix = matrix;
      		}
}


Next, to compile observationDeck.hx create the file compileObservationDeck.hxml, and run the command haxe compileObservationDeck.hxml. File observationDeck.swf will be created. You'll need the two files earth1Small.jpg, and foregroundObservationDeck.png also.

File compileObservationDeck.hxml:
-swf9 observationDeck.swf
-main ObservationDeck


Next, create an html file to display the SWF file.

File observationDeck.html
<html>
<head><title>haXe Flash</title></head>
<body bgcolor="#dddddd">
<object id="myswfFile" width="1523" height="175">
      <param name="movie" value="observationDeck.swf" />
      <param name="menu" value="false" />
      <param name="quality" value="high" />
      <param name="scale" value="noscale" />
      <embed src="observationDeck.swf" menu="false" quality="high" scale="noscale" width="1523"
      height="175" type="application/x-shockwave-flash" pluginspage=
      "http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash&amp;promoid=BIOW" />
      </object>
</body>
</html>


Go here to see the finished SWF file displayed in your browser.

Tech City Systems
SharePoint Foundation 2010 helps people work together. Using MarshallNet, a SharePoint 2010 website, with its document libraries, shared calendars, contact lists, task lists, announcements, etc., teams here at MSFC can work smarter and solve problems faster.

Document Libraries - On MarshallNet, your documents will be stored in a central, easily accessible location. Microsoft Office documents may be edited (with automatic versioning) directly from MarshallNet - no need to first download the file to your local computer. Moving files in and out of MarshallNet is easy, just drag-and-drop to and from your desktop folders. MarshallNet is secure too - It's possible to store ITAR/Export Controlled documents. User access/permissions at varying levels may be granted/denied. Also, files are backed up regularly.

Calendars - Your teams' calendars on MarshallNet are centrally located and easily accessible. Two way syncing between your Outlook and MarshallNet calendars is supported - Add an event in Outlook and it shows up on MarshallNet, and vice versa.

Contact Lists - Find people easily using MarshallNet contact lists. Look up someone's info, or send out mass emails to entire teams.

Alerts - You can set-up email alerts on any list at MarshallNet. Personally set-up alerts so you'll know when a new announcement is posted, when someone has uploaded a new document, or maybe when a calendar event has changed.

Announcements - MarshalNet is a great place to post announcements. Just add it and it shows up on the front page of your team's site. People who subscribe to alerts may be immediately notified too.

Workflow - Fire off actions when an event occurs. For example, a new document is uploaded to a library called Drafts triggering a workflow. The workflow may begin by sending all review team members an email explaining a new draft document has been uploaded and needs their approval. After they approve the document the workflow automatically moves the document to the Final Design document library. This is just an example - Workflows offer almost endless possibilities through customization.

Cost - SharePoint Foundation 2010 is free. The only cost is for a computer and database (MS SQL Server) seat.


MarshallNet makes sharing important information easy. Secure connections from all over the world allow users to work more efficiently than ever before.


Case study: Engineers Mark, John and Bill have been tasked by their program to explore why there's a vibration in the main engine - they're the Vibration Team or VTeam for short. On their program's SharePoint website they add a new recurring event for their VTeam weekly meetings - an email is automatically sent out to the program's members alerting them of this new event. Next they add two new document libraries - one, called VTeam Engineering Drafts is accessible by only Mark, John, and Bill. They don't want anyone else critiquing their draft documents. The other library is called VTeam Engineering - this is where final engineering documents are stored after they're reviewed and approved. More people have access to this library. Finally a task list called VTeam Tasks is created. This is, of course, where the VTeam keeps track of their tasks.

SharePoint will help the VTeam by giving them a safe centralized place to store their documents, where only people who need access have it. Tasks are easily managed, so everyone knows who's responsible for what and when it needs to be done. Finding people is easy because the team's contact list is stored on the website, and not on a secretary's personal workstation.



White Paper - Business Value of SharePoint Foundation 2010




Tech City Systems
SharePoint 2010's calendar updates after page load, so to remove times from and colorize events we can use a JavaScript function (with JQuery) added to the _spBodyOnLoadFunctionNames list. Mark Wilson at Planet Wilson SharePoint Blog wrote the script SharePoint 2010 Colour Calendar post SP1 update that colorizes events, and I have simply added the date removal function. Follow his more detailed instructions in his article to set up the initial script, then add my time removal function (removeTime) if desired. Below is Mark Wilson's script including my removeTime function:

_spBodyOnLoadFunctionNames.push('WaitForCalendarToLoad');

var SEPARATOR = "|||";

function WaitForCalendarToLoad() {
    // we will slightly rewrite this existing function as defined originally in SP.UI.ApplicationPages.Calendar.debug.js
    var pwold$4a = SP.UI.ApplicationPages.CalendarNotify.$4a;
    SP.UI.ApplicationPages.CalendarNotify.$4a = function () {
        pwold$4a();
        ColourCalendar();
	removeTime();
    }

    
    
	SP.UI.ApplicationPages.CalendarViewBase.prototype.resetSelection = function() {ULSSPg:;
		if (SP.UI.ApplicationPages.CalendarViewBase.prototype.$4u_1) {
			SP.UI.ApplicationPages.CalendarViewBase.prototype.$4u_1.$1D();
		}
		ColourCalendar();
		removeTime();
	}
}

function ColourCalendar() {
	if($('a:contains(' + SEPARATOR + ')') != null)
	{
		$('a:contains(' + SEPARATOR + ')').each(
			function (i) {
				$box = $(this).parents('div[title]');
				var colour = GetColourCodeFromCategory(GetCategory(this.innerHTML));
				this.innerHTML = GetActualText(this.innerHTML);
				$($box).attr("title", GetActualText($($box).attr("title")));
				$box.css('background-color', colour);
			});
	}
}

function removeTime() {
	$('div').filter('.ms-acal-sdiv').each(
			function (i) {
				this.innerHTML = this.innerHTML.replace(/\d{1,2}:\d\d [ap]m( - \d{1,2}:\d\d [ap]m)?/, "");
			});
}

function GetActualText(originalText) {
    var parts = originalText.split(SEPARATOR);
    return parts[0] + parts[2];
}

function GetCategory(originalText) {
    var parts = originalText.split(SEPARATOR);
    return parts[1];
}

function GetColourCodeFromCategory(category) {
    var colour = null;
    colour = '#FAFDFE';
    switch (category.trim().toLowerCase()) {
        case 'meeting':
            colour = '#E7F3F1';
            break;
        case 'work hours':
            colour = '#4FB8DB';
            break;
        case 'business':
            colour = "#C0E7F3";
            break;
        case 'cancelled':
            colour = "#FFdddd";
            break;
        case 'holiday':
            colour = "#e5ffec";
            break;
        case 'get-together':
            colour = "#E0F558";
            break;
        case 'gifts':
            colour = "#F558D5";
            break;
        case 'birthday':
            colour = "#6E80FA";
            break;
        case 'anniversary':
            colour = "#FF4040";
            break;
    }
    return colour;
}
Tech City Systems
A simple webcam hooked to a computer can work well as a motion detecting security camera. I've been using them for years now with great success. I even helped the police nab a burglar one time.

I have an old desktop computer running Windows XP, but pretty much any operating system will do. My USB webcam is made by Intel ... I'm not sure if Intel still makes webcams, but another brand like Microsoft or Logitec will work great too. As for motion detecting software I use Homewatcher, but Motion on Linux is even better. Other software which sends emails when motion is detected is custom written by me in Perl.

Homewatcher takes an image once a second comparing the latest image to the previous in each case. If a difference greater than a set threshhold is detected between the two latest images, the latest image is saved. The difference threshhold can be modified to get the sensitivity right. Once a minute a custom Perl script checks for new images, and if found emails them, and moves them to an old image storage area.

Following are some images of a burglar who broke into my house one morning. My security setup worked great, sending me images at work. I passed these images along to the police who were able to apprehend the culprit shortly thereafter.

First, he acted as if he was having car trouble, and went to my front door to see if I was home.




After snooping around a while realizing I wasn't home, he returned to the front of my house where he found a 2X4.



Here he sees my camera, but it's too late ... I already have pictures of him. You can see the 2X4 in his hand which I believe he used to knock my camera off its stand which was mounted on the inside of my window.



The following Perl program checks for new images every minute and emails them if found:

use File::Basename;
use SendMail::SendMail;


rename 'c:/oldSecurityImages/mailSecurityImages.log', 'c:/oldSecurityImages/oldMailSecurityImages.log';
open(LOG, '>c:/oldSecurityImages/mailSecurityImages.log');
select(LOG); $| = 1;
select(STDOUT); $| = 1;

$baseDir = "c:/oldSecurityImages/";

$time = localtime();
print "$time ... Program started\n\n";
print LOG "$time ... Program started\n\n";

$baseDir = "c:/Program Files/HomeWatcher/Image/";
chdir "$baseDir" or die "Couldn't cd to $baseDir: $!\n";

sleep 1;

opendir(DIR, $baseDir) or die "Couldn't open dir $baseDir: $!\n";
@images = grep {/.jpg/} readdir(DIR);
closedir(DIR);

$time = localtime();

print "\n";
$time = localtime();
print "$time ... Waiting for new images\n\n";
print LOG "$time ... Waiting for new images\n\n";

$dotCount = 0;

while (1) {
  opendir(DIR, $baseDir) or die "Couldn't open dir $baseDir: $!\n";
  @images = grep {/.jpg/} readdir(DIR);
  closedir(DIR);

  sleep 3; #Wait for images to be completely written to disk

  if ($#images >= 0) {
    $smtpserver	     = "yourSMTPServer";
    $sender          = "Me <yourEmail\@yourDomain>";
    $recipient	     = "<yourEmail\@yourDomain>";
    $replyto	     = $sender;
    $header	     = "X-Mailer";
    $headervalue     = "Perl SendMail Module 1.08";

    $numImages = $#images + 1;
    if ($numImages > 1) {
      $mailbodydata = "The following $numImages images were taken";
      $subject = "$numImages New Security Cam Images";
    }
    else {
      $mailbodydata = "The following image was taken";
      $subject = "1 New Security Cam Image";
    }

    $obj = new SendMail($smtpserver);

    $obj->setDebug($obj->OFF);

    $obj->From($sender);

    $obj->Subject($subject);

    $obj->To($recipient);

    $obj->ReplyTo($replyto);

    $obj->setMailHeader($header, $headervalue);

    $obj->setMailBody($mailbodydata);

    foreach $image (@images) {
      $obj->Attach($image);
    }

    if ($obj->sendMail() > -1) {
      $time = localtime();
      print "\n\n";
      print LOG "\n\n";
      ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
      $yearMonthDay = sprintf("%02d%02d%02d", $year % 100, $mon + 1, $mday);

      if (!-e "c:/oldSecurityImages/$yearMonthDay") {
	mkdir "c:/oldSecurityImages/$yearMonthDay";
      }

      foreach $image (@images) {
	rename $image, "c:/oldSecurityImages/$yearMonthDay/$image";
	print "$time ... Emailed image $image\n";
	print LOG "$time ... Emailed image $image\n";
      }
      print "\n";
      print LOG "\n";
      $dotCount = 0;
    }
    else {
      foreach $image (@images) {
	print "$time ... Couldn't email image $image\n";
	print LOG "$time ... Couldn't email image $image\n";
      }
      print "\n";
      print LOG "\n";
    }
  }

  if($#images < 0) {
    print ".";
    print LOG ".";
    $dotCount++;
    if($dotCount>14) {
      $time = localtime();
      print " $time\n";
      print LOG " $time\n";
      $dotCount = 0;
    }
  }

  sleep 57;
}
Tech City Systems
Google App Engine enables you to build and host web apps on the same systems that power Google applications. App Engine offers fast development and deployment; simple administration, with no need to worry about hardware, patches or backups; and effortless scalability. See why you might choose Google App Engine for your next project.

Front Man™ is an implementation of the Front Controller and Command patterns that serves as an ultra-lightweight framework for quickly creating Java web applications. See the article Front Controller Java Web Applications using Front Man for more information.

For this example I used Eclipse IDE for Java Developers along with the App Engine Java software development kit. This Getting Started Guide from Google will help you set your environment up. This guide assumes you've installed the Java SDK, Eclipse IDE for Java Developers and the Google App Engine SDK.

First, create a new Web Application Project. Select File->New->Web Application Project from the Eclipse main menu. Fill in Project name, and Package, and uncheck Use Google Web Toolkit as it's not needed for this project. Click Finish to complete this step.



The previous step creates a directory structure where all your application files are stored. In my case it's D:\Documents and Settings\username\workspace\GAEFMTest. You can run this simple skeleton application from within Eclipse now if you'd like, but to use the Front Man framework two libraries are needed - The Front Man library frontman-1.6.2.jar, and the Jakarta Commons Logging library commons-logging-1.1.1.jar (note: versions may have changed from when this guide was written). Copy both libraries to the directory GAEFMTest\war\WEB-INF\lib, then from the Eclipse Package Explorer window right click on the directory GAEFMTest\war\WEB-INF\lib and select Refresh. The libraries should now be visible in the list. Right click each library and select Build Path->Add to Build Path.

Now, modify the file GAEFMTest\war\WEB-INF\web.xml to look as follows:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

<servlet>  
     <servlet-name>CommandBroker</servlet-name>  
     <servlet-class>org.bibeault.frontman.CommandBroker</servlet-class>  
     <init-param>  
       <param-name>commandsPath</param-name>  
       <param-value>com.example.GAEFMTest</param-value>  
     </init-param>  
     <init-param>  
       <param-name>viewsPath</param-name>  
       <param-value>/WEB-INF</param-value>  
     </init-param>  
     <load-on-startup>1</load-on-startup>  
   </servlet>  
   
   <servlet-mapping>  
     <servlet-name>CommandBroker</servlet-name>  
     <url-pattern>/command/*</url-pattern>  
   </servlet-mapping>


	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>


Next, create GetHelloWorldMessageCommand command class (GetHelloWorldMessageCommand.java). From within Eclipse Package Explorer right click on the folder GAEFMTest\src\com.example.GAEFMTest and select New->File. Type GetHelloWorldMessageCommand.java and click Finish.
package com.example.GAEFMTest;

import org.bibeault.frontman.*;

import javax.servlet.ServletException;
import java.io.IOException;


public class GetHelloWorldMessageCommand implements Command {
	public void execute(CommandContext commandContext) throws ServletException, IOException {
		String helloWorld= "Hello World";

		commandContext.getSession().setAttribute("helloWorldMessage",  helloWorld);		
		commandContext.forwardToView("helloWorld");  		
	}
}


Next, write the view helloWorld.jsp in GAEFMTest\war\WEB-INF.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<%@page contentType="text/html;charset=ISO-8859-1" language="java"%>
	
<html>
<HEAD></HEAD>
<body>

${helloWorldMessage}
</body>
</html>


Next, write the HTML file (GAEFMTest\war\index.jsp) with a link to call the hello world command (getHelloWorldMessage).
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
	
<%@page contentType="text/html;charset=ISO-8859-1" language="java"%>

<html>
<HEAD></HEAD>
<body>

<a href='command/getHelloWorldMessage'>get hello world message.</a>
	
</body>
</html>


Finally, add <sessions-enabled>true</sessions-enabled> to the file GAEFMTest\war\WEB-INF\appengine-web.xml.
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
	<application></application>
	<version>1</version>
	
	<!-- Configure java.util.logging -->
	<system-properties>
		<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
	</system-properties>

    <sessions-enabled>true</sessions-enabled>	
</appengine-web-app>


Now, from the Eclipse IDE Package Explorer window right click on the GAEFMTest folder and select Debug As->Web Application. Point your browser to localhost:8888 and you should see your new application in action.
Tech City Systems
Here is a simple Front Man™ JAVA web application. Front Man is an implementation of the Front Controller and Command patterns that serves as an ultra-lightweight framework for quickly creating Java web applications. See the article Front Controller Java Web Applications using Front Man for more information. The example in this article uses the Apache/Tomcat servers and assumes you already have it up and running.


  1. Add the <servlet> and <servlet-mapping> entries for the Command Broker servlet in the deployment descriptor file web.xml:
       <servlet>  
         <servlet-name>CommandBroker</servlet-name>  
         <servlet-class>org.bibeault.frontman.CommandBroker</servlet-class>  
         <init-param>  
           <param-name>commandsPath</param-name>  
           <param-value>www.yourserver.commands</param-value>  
         </init-param>  
         <init-param>  
           <param-name>viewsPath</param-name>  
           <param-value>/WEB-INF/jsp</param-value>  
         </init-param>  
         <load-on-startup>1</load-on-startup>  
       </servlet>  
       
       <servlet-mapping>  
         <servlet-name>CommandBroker</servlet-name>  
         <url-pattern>/command/*</url-pattern>  
       </servlet-mapping>
  2. Drop the Front Man jar file into your application's WEB-INF/lib folder.
  3. Grab the Jakarta Commons Logging jar file and drop it into WEB-INF/lib.
  4. Write the GetHelloWorldMessageCommand command class (GetHelloWorldMessageCommand.java):
    package www.yourserver.commands;
    
    import org.bibeault.frontman.*;
    import javax.servlet.ServletException;
    import javax.servlet.http.*;
    
    public class GetHelloWorldMessageCommand implements Command {
    	public void execute(CommandContext commandContext) throws ServletException, IOException {
    		String helloWorld= "Hello World";
    
    		commandContext.getSession().setAttribute("helloWorldMessage",  helloWorld);		
    		commandContext.forwardToView("helloWorld");  		
    	}
    }
    
  5. Write the view (helloWorld.jsp):
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
    <%@page contentType="text/html;charset=ISO-8859-1" language="java"%>
    	
    <html>
    <HEAD></HEAD>
    <body>
    
    ${helloWorldMessage}
    </body>
    </html>
    

  6. Sample HTML file (index.jsp) with a link to call the hello world command (getHelloWorldMessage).
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
    	
    <%@page contentType="text/html;charset=ISO-8859-1" language="java"%>
    
    <html>
    <HEAD></HEAD>
    <body>
    
    <a href='command/getHelloWorldMessage'>get hello world message.</a>
    	
    </body>
    </html>
    
Tech City Systems
markItUp! is a JavaScript plugin built on the jQuery library. It allows you to turn any standard HTML textarea into a markup editor. Html, Textile, Wiki Syntax, Markdown, BBcode or even your own Markup system can be easily implemented. It's lightweight and customizable but it's not a WYSIWYG editor, and not meant to be.

Following is a markItUp! example. First include the jQuery and markItUp! libraries, and markItUp! CSS files. Then a text area with an id of addArticleBody is created, followed by a call to the JavaScript function markItUp which turns the ordinary text area into a complete markup editor.
<script type="text/javascript" src="include/jquery-1.3.2.min.js">
<script type="text/javascript" src="include/markitup/jquery.markitup.pack.js"></script>
<script type="text/javascript" src="include/markitup/sets/default/set.js"></script>
<link rel="stylesheet" type="text/css" href="include/markitup/skins/simple/style.css" />
<link rel="stylesheet" type="text/css" href="include/markitup/sets/default/style.css" />

<table width='720'>
    <tr>
	<td align='right'>body:</td><td align='left'><textarea cols="70" rows="15" id="addArticleBody" name='addArticleBody' class='addArticleBody'></textarea></td>
    </tr>
<table width='720'>

<script type="text/javascript">
	$(document).ready(function(){ $("#addArticleBody").markItUp(mySettings);});
</script>
Tech City Systems
The jQuery Form Plugin allows you to easily and unobtrusively upgrade HTML forms to use AJAX. The main methods, ajaxForm and ajaxSubmit, gather information from the form element to determine how to manage the submit process. Both of these methods support numerous options which allows you to have full control over how the data is submitted.

Here's an example. Just create a form and add a short JavaScript function call to initialize the form when the DOM is ready. Of course, don't forget to include the jQuery and the jquery.form.js libraries.
<script type="text/javascript" src="include/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="include/jquery.form.js"></script>

<form id="form" action="action" method="post">
    <table width='200'>
	<tr><td align='right'>Name:&nbsp;</td><td><input TYPE='text' NAME="name" id='name' size='12'></td></tr>
	<tr><td align='right'>field2:&nbsp;</td><td><input TYPE='text' NAME="field2"  size='12' ></td></tr>
	<tr><td colspan='2' align='center'><input type="submit"  value="Submit"/></td></tr>
    </table>
</form><

<script type="text/javascript">
    $(document).ready(function(){		
        var actionformOptions = { 
            success: actionSuccess,
	        clearForm: true
	    }; 
        $('#form').ajaxForm(actionformOptions); 
    });
</script>

When the form is submitted the name and field2 fields will be sent to action. If successful the function actionSuccess shown below will be called.
<script type="text/javascript">
    function actionSuccess() {
        do something here;
    }
</script>
Tech City Systems
DOM Window is a lightweight jQuery plugin for opening DOM windows that I use in my web apps. In the example below a DOM window is associated with the About anchor. When the link is clicked a DOM window opens and it's content is retrieved from the AJAX call /command/about.
<script type="text/javascript" src="include/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="include/jquery.DOMwindow.js"></script>

< div class="aboutButton">< a class="aboutButton menuButton">About</ a></ div >

<script type="text/javascript">
$('.aboutButton').openDOMWindow({ 
    height:430, 
    width:430, 
    windowBGColor:'#FFF',
    positionType:'centered', 
    eventType:'click', 
    windowSource:'ajax', 
    windowSourceURL:'command/about',
    overlayOpacity:'15',
    windowHTTPType:'post' 
});
</script>
Tech City Systems
jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. This article shows some short JQuery scripts I use in some of my web apps.

The following functions expand or contract a comment div. If the comment div is visible, the jQuery function slideUp is called to hide it. If the comment div is not visible, the comments are retrieved with a call to the server by the jQuery function load, and the div is made visible with the slideDown jQuery function.
<div id='comment${article.id}' style="display:none;"></div>

<script type="text/javascript">
function toggleComments(_articleid) {
    if($("#comment" + _articleid).is(":visible")) {
        $("#comment" + _articleid).slideUp(200);
    } else {
	getComments(_articleid);
    }
}

function getComments(_articleid) {
    $("#comment" + _articleid).load("/command/getcomments", {articleID:    _articleid}, function() {
	                    $("#comment" + _articleid).slideDown(200);
		        });
}
</script>
The following function calls the jQuery function load with parameter articleID to fill a div (id maintextpadder) with content retrieved from the server. The server's response from the call to gat.jsp is inserted into div maintextpadder.
function getArticles(_articleID) {
    $("#maintextpadder").load("gat.jsp", {articleID: _articleID});
}

The following function sends a simple post request with parameter to the server. A single callback function is executed when the request is complete (and only if the response has a successful response code).
function deleteArticle(_articleID) {
    if(confirm("Delete article?")) {
        $.post("/command/deleteArticle", { id: _articleID }, function (data) { getArticles(-1);} );
    }
}

The following JavaScript function demonstrates the jQuery function getJSON with a parameter and a callback function. The getJSON function loads JSON data using an HTTP GET request.
function getArticleJSON(_articleid) {
    $.getJSON('/command/getArticle', {id:  _articleid}, function(json){ 
	    $('#editid').val(_articleid);
	    $('#edittitle').val(json.title);
	    $('#editurl').val(json.url);
	    $('#editArticleBody').val(json.body);
        });
}
Example JAVA code to build a JSON string.
result = "{\"id\":\"" + articleID + "\",\"title\":\"" + resultSet.getString(1) + "\",\"url\":\"" + resultSet.getString(2) + "\",\"body\":\"" +  body + "\"}";
Tech City Systems
The Front Controller pattern has a single component that is responsible for processing application requests. A front controller centralizes functions such as view selection, and security, and applies them consistently across all views. A single servlet is used to handle all requests eliminating the need for every controller to be declared in the deployment descriptor.

An excellent implementation of Front Controller and Command patterns is Bear Bibeault's Front Man™. Front Man serves as a light-weight Java framework - Bear himself states "The purpose of Front Man is to provide an ultra-light-weight web framework that adheres to the principle that the answer to the question "How big should a framework be?" is "Barely enough!"". See the article Scriptless JSP Pages: The Front Man for great insight into the front controller pattern using Front Man.

For simple examples of Front Controller style apps using Front man try Example Java web application using Google App Engine with Front Man, and Sample Hello World Front Man JAVA web application.
Tech City Systems
Using a Linux computer, a web cam and some open-source software you can create time-lapse movies. Pretty much any web cam will do; I use a Microsoft Lifecam HD-5001 with 1280X720 resolution. I capture images at five minute intervals with Motion and then assemble the images into an MPEG-4 movie using ffmpeg. See this article for a shell script which calls ffmepeg to assemble an MPEG-4 movie from individual images.



To set up Motion I use the configuration file motion.conf shown below.
width 1280
height 720
mask_file motionMask.pgm #gray-scale mask file
smart_mask_speed 5
target_dir savedImages

text_right %d.%m.%Y\n%T\n%D.%q.%N
text_changes off
text_double on

jpeg_filename ../motionCapture/%Y/%m/%d/%H-%M-%S #Save images when motion is detected here

snapshot_interval 300 #take a snapshot every 5 minutes (300 seconds)
snapshot_filename %Y/%m/%d/%H-%M-%S
ffmpeg_timelapse 300
timelapse_filename %Y/%m/%d-timelapse
ffmpeg_timelapse_mode daily #create a new time-lapse movie every day

framerate 2
#minimum_frame_time 1

noise_level 32
threshold 800

despeckle EeEeEeEeDdDdDdDd
lightswitch 5
#setup_mode on
#locate on
output_motion on
#output_normal 0

Motion does three things with this configuration file. One is it saves a snapshot every 5 minutes. Two, it creates a time-lapse motion file every day from images taken every five minutes. Third it saves images (up to two per second) when motion is detected. So, Motion can be used to make time-lapse movies and act as a security camera at the same time!

I use the images taken at 5 minute intervals to create my own time-lapse movie in addition to the ones created by Motion. The following command will create an MPEG-4 movie from a series of appropriately named images:
ffmpeg  -y -i /tmp/img%05d.jpg -s 320x180 -b 1024k dreamCenterTimeLapse.mp4
Tech City Systems
Use the following shell script to create an MPEG 4 video using ffmpeg.

First, links are created for all of the images in a format friendly to ffmpeg. The links are numbered by modified time. ffmpeg is then called to create the mp4 video. Finally, the video is uploaded to a remote server using lftp.

#!/bin/bash

/bin/rm /tmp/*.jpg;
x=1;

for i in $(desampleImages.pl);
do counter=$(printf %05d $x);
   /bin/ln "$i" /tmp/img"$counter".jpg;
   x=$(($x+1));
done


/usr/bin/ffmpeg  -y -i /tmp/img%05d.jpg -s 640x360 -b 512k dreamCenterTimeLapse.mp4

/usr/bin/lftp -e 'set ftp:ssl-protect-data true;cd /images;put 'dreamCenterTimeLapse.mp4';quit' -u username,password ipAddress
To collect a list of images the script above uses the Perl program desampleImages.pl shown below. Only images meeting certain criteria are selected, then ordered by file modified time.
#!/usr/bin/perl
use File::Find;

$startDirectory = "/savedImages";

my @files = ();

find(\&runMain, $startDirectory);

sub runMain {
    if ( ((stat($_))[7] > 75000 ) && ($_=~/-00\.jpg$/) && ((stat($_))[9] > 1291528800)) {
	    push (@files, $File::Find::name);
    }
}

@files = sort { (stat($a))[9] <=> (stat($b))[9]} @files;
	
foreach $file (@files) {
	print "$file\n";
}
Tech City Systems
There's always been much debate over who should be ranked number 1 in college football. In 2009 both Alabama and Boise State had great football teams and finished 14-0, but what about strength of schedule?

The image to the the left shows teams listed in order of power rankings with the most powerful on top. Alabama's opponents are highlighted in crimson and Boise State's are in blue.

The graph below visually demonstrates the difference in opponent quality for the The Alabama Crimson Tide and Boise State Broncos by plotting their opponents' power ratings. Power ratings are from Jim Howell.




Some things to note are eleven of Alabama's opponents had a power rating above .6, but only three of Boise State's did. Alabama had eleven opponents with power ratings higher than Boise State's third highest ranked opponent. There was a string of at least seven games in the middle of the season where all of Alabama's opponents had power rankings above .6, but none of Boise State's did.

Note: Both teams played one non-1A opponent which had no power ranking, so they're listed as having a power ranking of .1.
Tech City Systems
  1. Modify Apache's httpd.conf by adding a virtual host section.
    <VirtualHost *:80>
        DocumentRoot "C:/Users/Username/Documents/java/servername/dist"
        ServerName www.servername.com
        <Directory "C:/Users/Username/Document/java/servername/dist">
            Options Indexes FollowSymLinks
            DirectoryIndex index.jsp
            AllowOverride None
            Order deny,allow
            allow from all
        </Directory>		
        <FilesMatch "(\.html|\.mhtml)$">
            SetHandler perl-script
            PerlResponsehandler servername
        </FilesMatch>
        CustomLog "logs/servername/access.log"  combined env=!dontlog
        ErrorLog "logs/servername/error.log"
    		
        JkMount /*.jsp ajp13
        JkMount /*.jspx ajp13
        JkMount /*.action ajp13
        JkMount /command/* ajp13
    </VirtualHost *:80>
    
  2. Modify Tomcat's /conf/server.xml file by adding a host section
    <Host appBase="C:/Users/Username/Documents/java/servername/dist" autoDeploy="false" name="www.servername.com" unpackWARs="false" xmlNamespaceAware="false" xmlValidation="false">
          < Listener append="true" className="org.apache.jk.config.ApacheConfig" forwardAll="false" modJk="C:/Program Files (x86)/Apache Software Foundation/Apache2.2/modules/mod_jk.so"/>
    </Host>
  3. Create a Context for the hostname in Tomcat (/conf/Catalina/hostname/ROOT.xml)
    <?xml version="1.0" encoding="UTF-8"?>
    <Context docBase="C:/Users/Username/Documents/java/servername/dist">
            <Resource name="jdbc/servername" auth="Container" 
    	        maxActive="100" maxIdle="30" maxWait="10000" 
    	        username="username" password="password" 
    	        driverClassName="com.mysql.jdbc.Driver" 
    	        url="jdbc:mysql://localhost/servername?autoReconnect=true" 
    	        logAbandoned="true" removeAbandoned="true" 
    	        removeAbandonedTimeout="60" type="javax.sql.DataSource" />
    </Context>
    		
    
  4. Create appbase directories and files as listed in 2 above. A good way to do this is to copy an existing directory structure.
    • Modify web.xml file as necessary (/web/WEB-INF/web.xml)
    • Modify build.xml file as necessary
    • Include necessary javascript files (/web/include)
    • Include necessary themes (/web/themes)
  5. Connect to database
    • Create database in MySQL and have Java Web Hosting create a blank database of the same name on their server. To copy database structure (tables, data, etc.) from the home server to JWH's server, export the home database to a file using phpMyAdmin. Then from JWH's control panel navigate to the desired database, select "Execute SQL", then select "Run SQL from file".
    • Add Resource fragment to ROOT.xml as in 3 above, and have Java Web Hosting add the same to the context on their server
    • Add context-param to the app's web.xml
      <context-param>
          <param-name>dbURL  
          <param-value>java:/comp/env/jdbc/servername  
      </context-param>
      
Tech City Systems
Following are some queries for a SharePoint (WSS 2.0) Microsoft SQL Server database. Of course, substitute your numbers (ListId, WebId, etc) where appropriate. You can use Microsoft SQL Server Management Studio to test these examples.

List 100 newest files sorted by TimeLastModified with most recent files listed first.
#For WSS 2.0
SET ROWCOUNT 100 SELECT *
FROM Docs WHERE (type='0')
ORDER BY TimeLastModified DESC

#For SharePoint 2010 ... Note table name change from WSS 2.0 (DOCS to ALLDocs)
SET ROWCOUNT 100 SELECT *
FROM [WSS_Content].[dbo].[AllDocs] WHERE (type='0')
ORDER BY TimeLastModified DESC

List newest 20 files at a subsite (WebId) sorted by TimeLastModified with most recently modified listed first
SET ROWCOUNT 20 SELECT *
FROM Docs
WHERE (WebId = '{97E31C64-DF29-4DBD-B83A-9F598C1C6A47}') AND (type='0')
ORDER BY TimeLastModified DESC

Sum of the size in MB of all of the files at a particular website (WebId)
SELECT SUM(CAST(CAST([Size] AS decimal(20, 2)) / 1048576 AS decimal(20, 2))) AS Expr1
FROM Docs
WHERE (WebId = '{97E31C64-DF29-4DBD-B83A-9F598C1C6A47}')

Sum of the size in MB of all of the files in a document library (ListId)
SELECT SUM(CAST(CAST([Size] AS decimal(20, 2)) / 1048576 AS decimal(20, 2))) AS Expr1
FROM Docs
WHERE (ListId = '{590EBCFE-47C0-4E08-B647-01412119EEED}')

List all files from a particular document library (ListId) sorted by TimeLastModified with the newest files listed first
SELECT *
FROM Docs
WHERE (ListId = '{590EBCFE-47C0-4E08-B647-01412119EEED}')
ORDER BY TimeLastModified DESC

List the sum of sizes in MB of files from each subsite (Webs) grouped by subsite url
SELECT Webs.FullUrl, SUM(CAST(CAST(Docs.[Size] AS decimal(20, 2)) / 1048576 AS decimal(20, 2))) AS 'Size in MB'
FROM Webs INNER JOIN Docs ON Webs.Id = Docs.WebId
WHERE (Docs.Type <> 1) AND (Docs.LeafName NOT LIKE '%.stp') AND (Docs.LeafName NOT LIKE '%.aspx') AND (Docs.LeafName NOT LIKE '%.xfp') AND 
                      (Docs.LeafName NOT LIKE '%.dwp') AND (Docs.LeafName NOT LIKE '%template%') AND (Docs.LeafName NOT LIKE '%.inf') AND 
                      (Docs.LeafName NOT LIKE '%.css')
GROUP BY Webs.FullUrl
Tech City Systems
$startDirectory = "Z:/Program Files";
$extension="aspx";
$find = "/_layouts/images/spoLogo.gif";
$replace = "onetidtpweb1 src="../../SiteImages/siteLogo.gif";
use File::Find;

find(&runMain, "$startDirectory");
sub runMain {
if (/$extension/ ) {
    $file= $_;
    next unless (-r $file);
    open(PAGE,"$File::Find::name") || die "I can't open $file";
    while(<PAGE>){
      $thisPage= $thisPage . $_;
    }
    close(PAGE);
    if($thisPage =~ s#$find#$replace#g) {
      open(PAGENEW,">$File::Find::name") || die "I can't write the new html to $file";
      print PAGENEW $thisPage;
      close(PAGENEW);
      print "$File::Find::name ";
    }
    $thisPage="";
  }
}
Tech City Systems
# No trailing slash on start directory
$startDirectory = "Z:/WINDOWS/system32/LogFiles";
$extension="log"; # Files with this extension will be searched
$find = "reyna"; # The text pattern to find
use File::Find;

find(&runMain, "$startDirectory");

sub runMain {
  if (/$extension/g ) {
    $file= $_;
    next unless (-r $file);
#    print "$file";
    open(PAGE,"$File::Find::name") || die "I can't open $file";
    $lineNumber = 0;
    while(<PAGE>) {
      $lineNumber++;
#      if((index $_, $find) > -1) {
      if(/($find)/i) {
#       print "$_";
        print "$1";
        print "$File::Find::name, $lineNumber";
      }
    }
    close(PAGE);
  }
}
Tech City Systems
The perl code below may be used to copy files between locations. This is handy for backing up files from one drive to another. The modification times are compared between source and destination files, and files are only copied if the source files are newer than the destination files.
use File::Find;
use File::Copy;
use File::Path;
# first remove files you don't wish to save
rmtree(["C:/Documents and Settings/User/Local Settings/Temp", "C:/Documents and Settings/User/Local Settings/Temporary Internet Files"], 1, 1);

$source = "c:/perlScripts";
$destination = "d:/perlScripts";
find(&wanted,  $source);

$source = "C:/Documents and Settings/User";
$destination = "d:/Documents and Settings/User";
find(&wanted,  $source);


sub wanted {
  my $relativeName = $File::Find::name;

  $relativeName =~ s/$source//;

  my $sourceName = "$source$relativeName";
  my $destinationName = "$destination$relativeName";

  if (-d $sourceName) {
    if (! -e $destinationName) {
      print "mkpath $destinationName";
      mkpath ($destinationName) or warn "mkpath $destinationName failed: $!";
    }
    else {
#      print "No mkpath ... directory already exists: $destinationName";
    }
  } else {
    if(! -e $destinationName) {
      print "Copy: $sourceName $destinationName";
      copy $sourceName, $destinationNameor warn "copy $sourceName $destinationName failed: $!";
    }
    else {
      $sourceModifiedTime = (stat($sourceName))[9];
      $destinationModifiedTime = (stat($destinationName))[9];
#     print "sourceModifiedTime: $sourceModifiedTime - destinationModifiedTime: $destinationModifiedTime";
      if ($sourceModifiedTime > $destinationModifiedTime) {
    print "Copy ... source newer than destination: $sourceName $destinationName";
    copy $sourceName, $destinationName or warn "copy $sourceName $destinationName failed: $!";
      }
      else {
#    print "No copy ... source no newer than destination: $sourceName $destinationName";
      }
    }
  }
}