You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by er...@apache.org on 2012/10/25 07:04:29 UTC

svn commit: r1401975 [24/29] - in /ofbiz/branches/20120329_portletWidget: ./ applications/accounting/config/ applications/accounting/data/ applications/accounting/script/org/ofbiz/accounting/invoice/ applications/accounting/script/org/ofbiz/accounting/...

Modified: ofbiz/branches/20120329_portletWidget/framework/images/webapp/images/jquery/ui/index.html
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/images/webapp/images/jquery/ui/index.html?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/images/webapp/images/jquery/ui/index.html (original)
+++ ofbiz/branches/20120329_portletWidget/framework/images/webapp/images/jquery/ui/index.html Thu Oct 25 05:04:09 2012
@@ -3,33 +3,33 @@
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
 		<title>jQuery UI Example Page</title>
-		<link type="text/css" href="css/ui-lightness/jquery-ui-1.8.13.custom.css" rel="stylesheet" />	
-		<script type="text/javascript" src="js/jquery-1.5.1.min.js"></script>
-		<script type="text/javascript" src="js/jquery-ui-1.8.13.custom.min.js"></script>
+		<link type="text/css" href="css/ui-lightness/jquery-ui-1.8.22.custom.css" rel="stylesheet" />
+		<script type="text/javascript" src="../jquery-1.8.0.min.js"></script>
+		<script type="text/javascript" src="js/jquery-ui-1.8.22.custom.min.js"></script>
 		<script type="text/javascript">
 			$(function(){
 
 				// Accordion
 				$("#accordion").accordion({ header: "h3" });
-	
+
 				// Tabs
 				$('#tabs').tabs();
-	
 
-				// Dialog			
+
+				// Dialog
 				$('#dialog').dialog({
 					autoOpen: false,
 					width: 600,
 					buttons: {
-						"Ok": function() { 
-							$(this).dialog("close"); 
-						}, 
-						"Cancel": function() { 
-							$(this).dialog("close"); 
-						} 
+						"Ok": function() {
+							$(this).dialog("close");
+						},
+						"Cancel": function() {
+							$(this).dialog("close");
+						}
 					}
 				});
-				
+
 				// Dialog Link
 				$('#dialog_link').click(function(){
 					$('#dialog').dialog('open');
@@ -40,24 +40,24 @@
 				$('#datepicker').datepicker({
 					inline: true
 				});
-				
+
 				// Slider
 				$('#slider').slider({
 					range: true,
 					values: [17, 67]
 				});
-				
+
 				// Progressbar
 				$("#progressbar").progressbar({
-					value: 20 
+					value: 20
 				});
-				
+
 				//hover states on the static widgets
 				$('#dialog_link, ul#icons li').hover(
-					function() { $(this).addClass('ui-state-hover'); }, 
+					function() { $(this).addClass('ui-state-hover'); },
 					function() { $(this).removeClass('ui-state-hover'); }
 				);
-				
+
 			});
 		</script>
 		<style type="text/css">
@@ -69,15 +69,15 @@
 			ul#icons {margin: 0; padding: 0;}
 			ul#icons li {margin: 2px; position: relative; padding: 4px 0; cursor: pointer; float: left;  list-style: none;}
 			ul#icons span.ui-icon {float: left; margin: 0 4px;}
-		</style>	
+		</style>
 	</head>
 	<body>
 	<h1>Welcome to jQuery UI!</h1>
 	<p style="font-size: 1.3em; line-height: 1.5; margin: 1em 0; width: 50%;">This page demonstrates the widgets you downloaded using the theme you selected in the download builder. We've included and linked to minified versions of <a href="js/jquery-1.5.1.min.js">jQuery</a>, your personalized copy of <a href="js/jquery-ui-1.8.13.custom.min.js">jQuery UI (js/jquery-ui-1.8.13.custom.min.js)</a>, and <a href="css/ui-lightness/jquery-ui-1.8.13.custom.css">css/ui-lightness/jquery-ui-1.8.13.custom.css</a> which imports the entire jQuery UI CSS Framework. You can choose to link a subset of the CSS Framework depending on your needs. </p>
-	<p style="font-size: 1.2em; line-height: 1.5; margin: 1em 0; width: 50%;">You've downloaded components and a theme that are compatible with jQuery 1.3+. Please make sure you are using jQuery 1.3+ in your production environment.</p>	
+	<p style="font-size: 1.2em; line-height: 1.5; margin: 1em 0; width: 50%;">You've downloaded components and a theme that are compatible with jQuery 1.3+. Please make sure you are using jQuery 1.3+ in your production environment.</p>
 
 	<p style="font-weight: bold; margin: 2em 0 1em; font-size: 1.3em;">YOUR COMPONENTS:</p>
-		
+
 		<!-- Accordion -->
 		<h2 class="demoHeaders">Accordion</h2>
 		<div id="accordion">
@@ -94,7 +94,7 @@
 				<div>Nam dui erat, auctor a, dignissim quis.</div>
 			</div>
 		</div>
-	
+
 		<!-- Tabs -->
 		<h2 class="demoHeaders">Tabs</h2>
 		<div id="tabs">
@@ -107,16 +107,16 @@
 			<div id="tabs-2">Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.</div>
 			<div id="tabs-3">Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.</div>
 		</div>
-	
+
 		<!-- Dialog NOTE: Dialog is not generated by UI in this demo so it can be visually styled in themeroller-->
 		<h2 class="demoHeaders">Dialog</h2>
 		<p><a href="#" id="dialog_link" class="ui-state-default ui-corner-all"><span class="ui-icon ui-icon-newwin"></span>Open Dialog</a></p>
-		
-		
+
+
 		<h2 class="demoHeaders">Overlay and Shadow Classes <em>(not currently used in UI widgets)</em></h2>
 		<div style="position: relative; width: 96%; height: 200px; padding:1% 4%; overflow:hidden;" class="fakewindowcontain">
 			<p>Lorem ipsum dolor sit amet,  Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. </p><p>Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie sceleri
 sque quam. </p><p>Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. </p><p>Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. </p>
-			
+
 			<!-- ui-dialog -->
 			<div class="ui-overlay"><div class="ui-widget-overlay"></div><div class="ui-widget-shadow ui-corner-all" style="width: 302px; height: 152px; position: absolute; left: 50px; top: 30px;"></div></div>
 			<div style="position: absolute; width: 280px; height: 130px;left: 50px; top: 30px; padding: 10px;" class="ui-widget ui-widget-content ui-corner-all">
@@ -124,24 +124,24 @@
 					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
 				</div>
 			</div>
-		
+
 		</div>
 
-		
+
 		<!-- ui-dialog -->
 		<div id="dialog" title="Dialog Title">
 			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
 		</div>
-			
-				
-				
+
+
+
 		<h2 class="demoHeaders">Framework Icons (content color preview)</h2>
 		<ul id="icons" class="ui-widget ui-helper-clearfix">
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-n"><span class="ui-icon ui-icon-carat-1-n"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-ne"><span class="ui-icon ui-icon-carat-1-ne"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-e"><span class="ui-icon ui-icon-carat-1-e"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-se"><span class="ui-icon ui-icon-carat-1-se"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-s"><span class="ui-icon ui-icon-carat-1-s"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-sw"><span class="ui-icon ui-icon-carat-1-sw"></span></li>
@@ -151,7 +151,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-2-e-w"><span class="ui-icon ui-icon-carat-2-e-w"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-n"><span class="ui-icon ui-icon-triangle-1-n"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-ne"><span class="ui-icon ui-icon-triangle-1-ne"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-e"><span class="ui-icon ui-icon-triangle-1-e"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-se"><span class="ui-icon ui-icon-triangle-1-se"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-s"><span class="ui-icon ui-icon-triangle-1-s"></span></li>
@@ -161,7 +161,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-n-s"><span class="ui-icon ui-icon-triangle-2-n-s"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-e-w"><span class="ui-icon ui-icon-triangle-2-e-w"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-n"><span class="ui-icon ui-icon-arrow-1-n"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-ne"><span class="ui-icon ui-icon-arrow-1-ne"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-e"><span class="ui-icon ui-icon-arrow-1-e"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-se"><span class="ui-icon ui-icon-arrow-1-se"></span></li>
@@ -171,7 +171,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-nw"><span class="ui-icon ui-icon-arrow-1-nw"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-n-s"><span class="ui-icon ui-icon-arrow-2-n-s"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-ne-sw"><span class="ui-icon ui-icon-arrow-2-ne-sw"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-e-w"><span class="ui-icon ui-icon-arrow-2-e-w"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-se-nw"><span class="ui-icon ui-icon-arrow-2-se-nw"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-n"><span class="ui-icon ui-icon-arrowstop-1-n"></span></li>
@@ -181,7 +181,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-n"><span class="ui-icon ui-icon-arrowthick-1-n"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-ne"><span class="ui-icon ui-icon-arrowthick-1-ne"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-e"><span class="ui-icon ui-icon-arrowthick-1-e"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-se"><span class="ui-icon ui-icon-arrowthick-1-se"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-s"><span class="ui-icon ui-icon-arrowthick-1-s"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-sw"><span class="ui-icon ui-icon-arrowthick-1-sw"></span></li>
@@ -191,7 +191,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-ne-sw"><span class="ui-icon ui-icon-arrowthick-2-ne-sw"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-e-w"><span class="ui-icon ui-icon-arrowthick-2-e-w"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-se-nw"><span class="ui-icon ui-icon-arrowthick-2-se-nw"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-n"><span class="ui-icon ui-icon-arrowthickstop-1-n"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-e"><span class="ui-icon ui-icon-arrowthickstop-1-e"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-s"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span></li>
@@ -201,7 +201,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-e"><span class="ui-icon ui-icon-arrowreturnthick-1-e"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-s"><span class="ui-icon ui-icon-arrowreturnthick-1-s"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-w"><span class="ui-icon ui-icon-arrowreturn-1-w"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-n"><span class="ui-icon ui-icon-arrowreturn-1-n"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-e"><span class="ui-icon ui-icon-arrowreturn-1-e"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-s"><span class="ui-icon ui-icon-arrowreturn-1-s"></span></li>
@@ -211,7 +211,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-s"><span class="ui-icon ui-icon-arrowrefresh-1-s"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4"><span class="ui-icon ui-icon-arrow-4"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4-diag"><span class="ui-icon ui-icon-arrow-4-diag"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-extlink"><span class="ui-icon ui-icon-extlink"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-newwin"><span class="ui-icon ui-icon-newwin"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-refresh"><span class="ui-icon ui-icon-refresh"></span></li>
@@ -221,7 +221,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-folder-collapsed"><span class="ui-icon ui-icon-folder-collapsed"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-folder-open"><span class="ui-icon ui-icon-folder-open"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-document"><span class="ui-icon ui-icon-document"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-document-b"><span class="ui-icon ui-icon-document-b"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-note"><span class="ui-icon ui-icon-note"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></li>
@@ -231,7 +231,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-person"><span class="ui-icon ui-icon-person"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-print"><span class="ui-icon ui-icon-print"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-trash"><span class="ui-icon ui-icon-trash"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-locked"><span class="ui-icon ui-icon-locked"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-unlocked"><span class="ui-icon ui-icon-unlocked"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-bookmark"><span class="ui-icon ui-icon-bookmark"></span></li>
@@ -241,7 +241,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-calculator"><span class="ui-icon ui-icon-calculator"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-cart"><span class="ui-icon ui-icon-cart"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-pencil"><span class="ui-icon ui-icon-pencil"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-clock"><span class="ui-icon ui-icon-clock"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-disk"><span class="ui-icon ui-icon-disk"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-calendar"><span class="ui-icon ui-icon-calendar"></span></li>
@@ -251,7 +251,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-wrench"><span class="ui-icon ui-icon-wrench"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-gear"><span class="ui-icon ui-icon-gear"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-heart"><span class="ui-icon ui-icon-heart"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-star"><span class="ui-icon ui-icon-star"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-link"><span class="ui-icon ui-icon-link"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-cancel"><span class="ui-icon ui-icon-cancel"></span></li>
@@ -261,7 +261,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-minusthick"><span class="ui-icon ui-icon-minusthick"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-close"><span class="ui-icon ui-icon-close"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-closethick"><span class="ui-icon ui-icon-closethick"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-key"><span class="ui-icon ui-icon-key"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-lightbulb"><span class="ui-icon ui-icon-lightbulb"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-scissors"><span class="ui-icon ui-icon-scissors"></span></li>
@@ -272,7 +272,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-video"><span class="ui-icon ui-icon-video"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-script"><span class="ui-icon ui-icon-script"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-alert"><span class="ui-icon ui-icon-alert"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-info"><span class="ui-icon ui-icon-info"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-notice"><span class="ui-icon ui-icon-notice"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-help"><span class="ui-icon ui-icon-help"></span></li>
@@ -284,7 +284,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-pin-s"><span class="ui-icon ui-icon-pin-s"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-play"><span class="ui-icon ui-icon-play"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-pause"><span class="ui-icon ui-icon-pause"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-next"><span class="ui-icon ui-icon-seek-next"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-prev"><span class="ui-icon ui-icon-seek-prev"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-end"><span class="ui-icon ui-icon-seek-end"></span></li>
@@ -294,7 +294,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-volume-off"><span class="ui-icon ui-icon-volume-off"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-volume-on"><span class="ui-icon ui-icon-volume-on"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-power"><span class="ui-icon ui-icon-power"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-signal-diag"><span class="ui-icon ui-icon-signal-diag"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-signal"><span class="ui-icon ui-icon-signal"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-0"><span class="ui-icon ui-icon-battery-0"></span></li>
@@ -304,7 +304,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-plus"><span class="ui-icon ui-icon-circle-plus"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-minus"><span class="ui-icon ui-icon-circle-minus"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-close"><span class="ui-icon ui-icon-circle-close"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-e"><span class="ui-icon ui-icon-circle-triangle-e"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-s"><span class="ui-icon ui-icon-circle-triangle-s"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-w"><span class="ui-icon ui-icon-circle-triangle-w"></span></li>
@@ -314,7 +314,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-w"><span class="ui-icon ui-icon-circle-arrow-w"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-n"><span class="ui-icon ui-icon-circle-arrow-n"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomin"><span class="ui-icon ui-icon-circle-zoomin"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomout"><span class="ui-icon ui-icon-circle-zoomout"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-check"><span class="ui-icon ui-icon-circle-check"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-plus"><span class="ui-icon ui-icon-circlesmall-plus"></span></li>
@@ -324,7 +324,7 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-minus"><span class="ui-icon ui-icon-squaresmall-minus"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-close"><span class="ui-icon ui-icon-squaresmall-close"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-vertical"><span class="ui-icon ui-icon-grip-dotted-vertical"></span></li>
-		
+
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-horizontal"><span class="ui-icon ui-icon-grip-dotted-horizontal"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-vertical"><span class="ui-icon ui-icon-grip-solid-vertical"></span></li>
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-horizontal"><span class="ui-icon ui-icon-grip-solid-horizontal"></span></li>
@@ -332,31 +332,31 @@
 		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-diagonal-se"><span class="ui-icon ui-icon-grip-diagonal-se"></span></li>
 		</ul>
 
-	
+
 		<!-- Slider -->
 		<h2 class="demoHeaders">Slider</h2>
 		<div id="slider"></div>
-	
+
 		<!-- Datepicker -->
 		<h2 class="demoHeaders">Datepicker</h2>
 		<div id="datepicker"></div>
-	
+
 		<!-- Progressbar -->
-		<h2 class="demoHeaders">Progressbar</h2>	
+		<h2 class="demoHeaders">Progressbar</h2>
 		<div id="progressbar"></div>
-			
+
 		<!-- Highlight / Error -->
 		<h2 class="demoHeaders">Highlight / Error</h2>
 		<div class="ui-widget">
-			<div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0 .7em;"> 
+			<div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0 .7em;">
 				<p><span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>
 				<strong>Hey!</strong> Sample ui-state-highlight style.</p>
 			</div>
 		</div>
 		<br/>
 		<div class="ui-widget">
-			<div class="ui-state-error ui-corner-all" style="padding: 0 .7em;"> 
-				<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span> 
+			<div class="ui-state-error ui-corner-all" style="padding: 0 .7em;">
+				<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>
 				<strong>Alert:</strong> Sample ui-state-error style.</p>
 			</div>
 		</div>

Modified: ofbiz/branches/20120329_portletWidget/framework/images/webapp/images/selectall.js
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/images/webapp/images/selectall.js?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/images/webapp/images/selectall.js (original)
+++ ofbiz/branches/20120329_portletWidget/framework/images/webapp/images/selectall.js Thu Oct 25 05:04:09 2012
@@ -426,7 +426,7 @@ function ajaxSubmitFormUpdateAreas(form,
    });
 }
 
-/** Enable auto-completion for text elements.
+/** Enable auto-completion for text elements, with a possible span of tooltip class showing description.
  * @param areaCsvString The area CSV string. The CSV string is a flat array in the
  * form of: areaId, target, target parameters [, areaId, target, target parameters...].
 */

Modified: ofbiz/branches/20120329_portletWidget/framework/jetty/src/org/ofbiz/jetty/container/JettyContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/jetty/src/org/ofbiz/jetty/container/JettyContainer.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/jetty/src/org/ofbiz/jetty/container/JettyContainer.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/jetty/src/org/ofbiz/jetty/container/JettyContainer.java Thu Oct 25 05:04:09 2012
@@ -61,9 +61,7 @@ public class JettyContainer implements C
     private String name;
     private Map<String, Server> servers = new HashMap<String, Server>();
 
-    /**
-     * @see org.ofbiz.base.container.Container#init(String[] args, String name, String configFile)
-     */
+    @Override
     public void init(String[] args, String name, String configFile) throws ContainerException {
         this.name = name;
         // configure JSSE properties

Modified: ofbiz/branches/20120329_portletWidget/framework/resources/templates/ofbiz-component.xml
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/resources/templates/ofbiz-component.xml?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/resources/templates/ofbiz-component.xml (original)
+++ ofbiz/branches/20120329_portletWidget/framework/resources/templates/ofbiz-component.xml Thu Oct 25 05:04:09 2012
@@ -17,7 +17,8 @@
     <entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel.xml"/>
     <!-- <entity-resource type="eca" reader-name="main" loader="main" location="entitydef/eecas.xml"/> -->
     <entity-resource type="data" reader-name="seed" loader="main" location="data/@component-resource-name@TypeData.xml"/>
-    <entity-resource type="data" reader-name="seed" loader="main" location="data/@component-resource-name@SecurityData.xml"/>
+    <entity-resource type="data" reader-name="seed" loader="main" location="data/@component-resource-name@SecurityPermissionSeedData.xml"/>
+    <entity-resource type="data" reader-name="demo" loader="main" location="data/@component-resource-name@SecurityGroupDemoData.xml"/>
     <entity-resource type="data" reader-name="demo" loader="main" location="data/@component-resource-name@DemoData.xml"/>
 
     <!-- service resources: model(s), eca(s) and group definitions -->
@@ -36,4 +37,4 @@
         location="webapp/@webapp-name@"
         base-permission="OFBTOOLS,@base-permission@"
         mount-point="/@webapp-name@"/>
-</ofbiz-component>
\ No newline at end of file
+</ofbiz-component>

Modified: ofbiz/branches/20120329_portletWidget/framework/service/build.xml
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/build.xml?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/build.xml (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/build.xml Thu Oct 25 05:04:09 2012
@@ -31,6 +31,7 @@ under the License.
 
     <path id="local.class.path">
         <fileset dir="${lib.dir}" includes="*.jar"/>
+        <fileset dir="../.." includes="ofbiz.jar"/>
         <fileset dir="../base/lib" includes="*.jar"/>
         <fileset dir="../base/lib/commons" includes="*.jar"/>
         <fileset dir="../base/lib/j2eespecs" includes="*.jar"/>

Modified: ofbiz/branches/20120329_portletWidget/framework/service/config/serviceengine.xml
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/config/serviceengine.xml?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/config/serviceengine.xml (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/config/serviceengine.xml Thu Oct 25 05:04:09 2012
@@ -25,15 +25,16 @@ under the License.
         <!-- Name of the service to use for authorization -->
         <authorization service-name="userLogin"/>
 
-        <!-- Thread pool configuration (max/min threads, uses to live and time to live) -->
+        <!-- Job poller configuration. Many of these attributes are set to the job poller defaults, but they are included here for convenience. -->
         <thread-pool send-to-pool="pool"
                      purge-job-days="4"
                      failed-retry-min="3"
-                     ttl="18000000"
-                     min-threads="5"
-                     max-threads="15"
+                     ttl="120000"
+                     jobs="100"
+                     min-threads="2"
+                     max-threads="5"
                      poll-enabled="true"
-                     poll-db-millis="20000">
+                     poll-db-millis="30000">
             <run-from-pool name="pool"/>
         </thread-pool>
 
@@ -58,7 +59,6 @@ under the License.
         <engine name="jms" class="org.ofbiz.service.jms.JmsServiceEngine"/>
         <engine name="rmi" class="org.ofbiz.service.rmi.RmiServiceEngine"/>
         <engine name="soap" class="org.ofbiz.service.engine.SOAPClientEngine"/>
-        <engine name="ofbiz-workflow" class="org.ofbiz.workflow.WorkflowEngine"/>
         <!-- The engine xml-rpc-local is only used by a test service and for
              this reason it is configured to run on port 8081 (see test-containers.xml);
              in order to use this in OFBiz change the port accordingly (for demo the default

Modified: ofbiz/branches/20120329_portletWidget/framework/service/data/ScheduledServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/data/ScheduledServices.xml?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/data/ScheduledServices.xml (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/data/ScheduledServices.xml Thu Oct 25 05:04:09 2012
@@ -19,5 +19,7 @@ under the License.
 -->
 <entity-engine-xml>
     <TemporalExpression tempExprId="MIDNIGHT_DAILY" tempExprTypeId="FREQUENCY" description="Daily Midnight" date1="2000-01-01 00:00:00.000" integer1="5" integer2="1"/>
+    <!-- The JobManager handles purging old jobs now.
     <JobSandbox jobId="PURGE_OLD_JOBS" jobName="Purge Old Jobs" runTime="2000-01-01 00:00:00.000" serviceName="purgeOldJobs" poolId="pool" runAsUser="system" tempExprId="MIDNIGHT_DAILY" maxRecurrenceCount="-1"/>
+    -->
 </entity-engine-xml>

Modified: ofbiz/branches/20120329_portletWidget/framework/service/dtd/service-config.xsd
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/dtd/service-config.xsd?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/dtd/service-config.xsd (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/dtd/service-config.xsd Thu Oct 25 05:04:09 2012
@@ -56,40 +56,123 @@ under the License.
         <xs:attribute type="xs:string" name="service-name" use="required"/>
     </xs:attributeGroup>
     <xs:element name="thread-pool">
+        <xs:annotation>
+            <xs:documentation>
+                Configures the Job Manager and Job Poller.
+            </xs:documentation>
+        </xs:annotation>
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="run-from-pool"/>
+                <xs:element name="run-from-pool" minOccurs="0" maxOccurs="unbounded">
+                    <xs:annotation>
+                        <xs:documentation>
+                            The Job Pool(s) this server should service. Only valid when the
+                            thread-pool element poll-enabled attribute is set to "true".
+                            A database can contain any number of job pools, and different
+                            servers can service different pools. Since the pools are in a common
+                            (shared) database, there is the potential for database locking problems
+                            when multiple servers service the pools.
+                        </xs:documentation>
+                    </xs:annotation>
+                    <xs:complexType>
+                        <xs:attribute type="xs:string" name="name" use="required" />
+                    </xs:complexType>
+                </xs:element>
             </xs:sequence>
-            <xs:attributeGroup ref="attlist.thread-pool"/>
+            <xs:attribute type="xs:string" name="send-to-pool" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The Job Pool that jobs originating on this server should be sent to.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:nonNegativeInteger" name="purge-job-days" default="30">
+                <xs:annotation>
+                    <xs:documentation>
+                        The number of days to keep completed/canceled jobs in the database.
+                        Only valid when the poll-enabled attribute is set to "true".
+                        This value should be reduced for applications that create a lot of jobs.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:nonNegativeInteger" name="failed-retry-min" default="30">
+                <xs:annotation>
+                    <xs:documentation>
+                        The number of minutes to wait before retrying a failed job.
+                        Only valid when the poll-enabled attribute is set to "true".
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:nonNegativeInteger" name="ttl">
+                <xs:annotation>
+                    <xs:documentation>
+                        Idle queue service thread lifespan in milliseconds. Defaults to "120000" (2 minutes).
+                        This setting should be a multiple of the poll-db-millis attribute value. If there are
+                        no jobs after multiple database polls, then idle queue service threads should be
+                        released - to help keep the system responsive.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:nonNegativeInteger" name="jobs">
+                <xs:annotation>
+                    <xs:documentation>
+                        Job queue size. Defaults to "100".
+                        The default setting is for "normal" installations. If an application generates a lot of jobs,
+                        then this setting should be increased. If you are getting "Unable to queue job"
+                        exceptions, then increase this setting gradually until the exceptions stop appearing. 
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:nonNegativeInteger" name="min-threads">
+                <xs:annotation>
+                    <xs:documentation>
+                        Minimum number of queue service threads. Defaults to "1".
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:nonNegativeInteger" name="max-threads">
+                <xs:annotation>
+                    <xs:documentation>
+                        Maximum number of queue service threads. Defaults to "5".
+                        The Job Poller will add jobs to the job queue until it is full, then it will add
+                        queue service threads until the maximum in this setting is reached. The additional
+                        queue service threads are released when they are idle for the period of time
+                        set in the ttl attribute.
+                        The default setting is for a server with two CPUs. The value can be increased
+                        on servers with more CPUs. Higher values do not always result in better throughput -
+                        additional threads can slow the server down because of thread maintenance overhead.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="poll-enabled">
+                <xs:annotation>
+                    <xs:documentation>
+                        Enable database polling. Defaults to "true".
+                        In multi-server (load balanced) environments, only one server should have this
+                        attribute set to "true" - otherwise you might experience database locking problems.
+                    </xs:documentation>
+                </xs:annotation>
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+            <xs:attribute type="xs:nonNegativeInteger" name="poll-db-millis">
+                <xs:annotation>
+                    <xs:documentation>
+                        Database polling interval in milliseconds. Defaults to "30000" (30 seconds).
+                        Only valid when the poll-enabled attribute is set to "true".
+                        When the database is polled, there will be a burst of activity (database "hits")
+                        while the Job Manager queues jobs, then after the burst each queued job will
+                        update the database after it runs. Decreasing this value will increase database activity.
+                        Increasing this value will reduce the timeliness of job servicing.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.thread-pool">
-        <xs:attribute type="xs:string" name="send-to-pool" use="required"/>
-        <xs:attribute type="xs:nonNegativeInteger" name="purge-job-days" default="30"/>
-        <xs:attribute type="xs:nonNegativeInteger" name="failed-retry-min" default="30"/>
-        <xs:attribute type="xs:nonNegativeInteger" name="ttl" use="required"/>
-        <xs:attribute type="xs:nonNegativeInteger" name="wait-millis"/> <!-- deprecated -->
-        <xs:attribute type="xs:nonNegativeInteger" name="jobs"/> <!-- deprecated -->
-        <xs:attribute type="xs:nonNegativeInteger" name="min-threads" use="required"/>
-        <xs:attribute type="xs:nonNegativeInteger" name="max-threads" use="required"/>
-        <xs:attribute name="poll-enabled" default="true">
-            <xs:simpleType>
-                <xs:restriction base="xs:token">
-                    <xs:enumeration value="true"/>
-                    <xs:enumeration value="false"/>
-                </xs:restriction>
-            </xs:simpleType>
-        </xs:attribute>
-        <xs:attribute type="xs:nonNegativeInteger" name="poll-db-millis" use="required"/>
-    </xs:attributeGroup>
-    <xs:element name="run-from-pool">
-        <xs:complexType>
-            <xs:attributeGroup ref="attlist.run-from-pool"/>
-        </xs:complexType>
-    </xs:element>
-    <xs:attributeGroup name="attlist.run-from-pool">
-        <xs:attribute type="xs:string" name="name" use="required"/>
-    </xs:attributeGroup>
     <xs:element name="engine">
         <xs:complexType>
             <xs:sequence>

Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelService.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelService.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelService.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelService.java Thu Oct 25 05:04:09 2012
@@ -1374,6 +1374,7 @@ public class ModelService extends Abstra
         /* null Element */
         Element stdNullElement = document.createElement("xsd:element");
         stdNullElement.setAttribute("name", "null");
+        stdNullElement.setAttribute("nillable", "true");
         Element stdNullElement0 = document.createElement("xsd:complexType");
         stdNullElement.appendChild(stdNullElement0);
         Element stdNullElement1 = document.createElement("xsd:attribute");
@@ -1381,7 +1382,6 @@ public class ModelService extends Abstra
         stdNullElement1.setAttribute("name", "value");
         stdNullElement1.setAttribute("type", "xsd:string");
         stdNullElement1.setAttribute("use", "required");
-        stdNullElement1.setAttribute("nillable", "true");
         schema.appendChild(stdNullElement);
         /* std-String Element */
         Element stdStringElement = document.createElement("xsd:element");
@@ -1685,7 +1685,6 @@ public class ModelService extends Abstra
         mapValueComplexTypeNull.setAttribute("ref", "tns:null");
         mapValueComplexTypeNull.setAttribute("minOccurs", "1");
         mapValueComplexTypeNull.setAttribute("maxOccurs", "1");
-        mapValueComplexTypeNull.setAttribute("nillable", "true");
         mapValueComplexType0.appendChild(mapValueComplexTypeNull);
         Element mapValueComplexType1 = document.createElement("xsd:element");
         mapValueComplexType1.setAttribute("ref", "tns:std-String");
@@ -1829,7 +1828,6 @@ public class ModelService extends Abstra
         colCollectionComplexTypeNull.setAttribute("ref", "tns:null");
         colCollectionComplexTypeNull.setAttribute("minOccurs", "0");
         colCollectionComplexTypeNull.setAttribute("maxOccurs", "unbounded");
-        colCollectionComplexTypeNull.setAttribute("nillable", "true");
         colCollectionComplexType0.appendChild(colCollectionComplexTypeNull);
         Element colCollectionComplexType1 = document.createElement("xsd:element");
         colCollectionComplexType1.setAttribute("ref", "tns:std-String");

Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceDispatcher.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceDispatcher.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceDispatcher.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceDispatcher.java Thu Oct 25 05:04:09 2012
@@ -166,7 +166,6 @@ public class ServiceDispatcher {
 
     /**
      * Registers the loader with this ServiceDispatcher
-     * @param name the local dispatcher
      * @param context the context of the local dispatcher
      */
     public void register(DispatchContext context) {
@@ -835,8 +834,6 @@ public class ServiceDispatcher {
             // shutdown JMS listeners
             jlf.closeListeners();
         }
-        // shutdown the job scheduler
-        jm.shutdown();
     }
 
     // checks if parameters were passed for authentication

Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceUtil.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceUtil.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceUtil.java Thu Oct 25 05:04:09 2012
@@ -369,6 +369,7 @@ public class ServiceUtil {
     }
 
     public static Map<String, Object> purgeOldJobs(DispatchContext dctx, Map<String, ? extends Object> context) {
+        Debug.logWarning("WARNING: purgeOldJobs service invoked. This service is obsolete - the Job Scheduler will purge old jobs automatically.", module);
         String sendPool = ServiceConfigUtil.getSendPool();
         int daysToKeep = ServiceConfigUtil.getPurgeJobDays();
         Delegator delegator = dctx.getDelegator();

Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/engine/GenericAsyncEngine.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/engine/GenericAsyncEngine.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/engine/GenericAsyncEngine.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/engine/GenericAsyncEngine.java Thu Oct 25 05:04:09 2012
@@ -20,7 +20,6 @@ package org.ofbiz.service.engine;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.util.Date;
 import java.util.Map;
 
 import org.ofbiz.base.util.Debug;
@@ -103,7 +102,7 @@ public abstract class GenericAsyncEngine
 
                 // Create the job info
                 String jobId = dispatcher.getDelegator().getNextSeqId("JobSandbox");
-                String jobName = Long.toString((new Date().getTime()));
+                String jobName = Long.toString(System.currentTimeMillis());
 
                 Map<String, Object> jFields = UtilMisc.toMap("jobId", jobId, "jobName", jobName, "runTime", UtilDateTime.nowTimestamp());
                 jFields.put("poolId", ServiceConfigUtil.getSendPool());
@@ -137,7 +136,7 @@ public abstract class GenericAsyncEngine
         } else {
             JobManager jMgr = dispatcher.getJobManager();
             if (jMgr != null) {
-                String name = Long.toString(new Date().getTime());
+                String name = Long.toString(System.currentTimeMillis());
                 String jobId = modelService.name + "." + name;
                 job = new GenericServiceJob(dctx, jobId, name, modelService.name, context, requester);
                 try {

Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/AbstractJob.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/AbstractJob.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/AbstractJob.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/AbstractJob.java Thu Oct 25 05:04:09 2012
@@ -18,68 +18,101 @@
  *******************************************************************************/
 package org.ofbiz.service.job;
 
+import java.util.Date;
+
+import org.ofbiz.base.util.Assert;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.entity.transaction.GenericTransactionException;
+import org.ofbiz.entity.transaction.TransactionUtil;
+
 /**
- * Abstract Service Job - Invokes a service
+ * Abstract Job.
  */
-@SuppressWarnings("serial")
 public abstract class AbstractJob implements Job {
 
     public static final String module = AbstractJob.class.getName();
 
-    protected long runtime = -1;
-    protected long sequence = 0;
-    private String jobId;
-    private String jobName;
-    private boolean queued = false;
+    private final String jobId;
+    private final String jobName;
+    protected State currentState = State.CREATED;
+    private long elapsedTime = 0;
+    private final Date startTime = new Date();
 
     protected AbstractJob(String jobId, String jobName) {
+        Assert.notNull("jobId", jobId, "jobName", jobName);
         this.jobId = jobId;
         this.jobName = jobName;
     }
 
-    /**
-     * Returns the time to run in milliseconds.
-     */
-    public long getRuntime() {
-        return runtime;
+    @Override
+    public State currentState() {
+        return currentState;
     }
 
-    /**
-     * Returns true if this job is still valid.
-     */
-    public boolean isValid() {
-        if (runtime > 0)
-            return true;
-        return false;
-    }
-
-    /**
-     * Returns the ID of this Job.
-     */
+    @Override
     public String getJobId() {
         return this.jobId;
     }
 
-    /**
-     * Returns the name of this Job.
-     */
+    @Override
     public String getJobName() {
         return this.jobName;
     }
 
-    /**
-     * Flags this job as 'is-queued'
-     */
+    @Override
     public void queue() throws InvalidJobException {
-        this.queued = true;
+        if (currentState != State.CREATED) {
+            throw new InvalidJobException("Illegal state change");
+        }
+        this.currentState = State.QUEUED;
+    }
+
+    @Override
+    public void deQueue() throws InvalidJobException {
+        if (currentState != State.QUEUED) {
+            throw new InvalidJobException("Illegal state change");
+        }
+        this.currentState = State.CREATED;
     }
 
     /**
-     *  Executes the Job.
+     *  Executes this Job. The {@link #run()} method calls this method.
      */
     public abstract void exec() throws InvalidJobException;
 
-    public boolean isQueued() {
-        return queued;
+    @Override
+    public void run() {
+        long startMillis = System.currentTimeMillis();
+        try {
+            exec();
+        } catch (InvalidJobException e) {
+            Debug.logWarning(e.getMessage(), module);
+        }
+        // sanity check; make sure we don't have any transactions in place
+        try {
+            // roll back current TX first
+            if (TransactionUtil.isTransactionInPlace()) {
+                Debug.logWarning("*** NOTICE: JobInvoker finished w/ a transaction in place! Rolling back.", module);
+                TransactionUtil.rollback();
+            }
+            // now resume/rollback any suspended txs
+            if (TransactionUtil.suspendedTransactionsHeld()) {
+                int suspended = TransactionUtil.cleanSuspendedTransactions();
+                Debug.logWarning("Resumed/Rolled Back [" + suspended + "] transactions.", module);
+            }
+        } catch (GenericTransactionException e) {
+            Debug.logWarning(e, module);
+        }
+        elapsedTime = System.currentTimeMillis() - startMillis;
+    }
+
+    @Override
+    public long getRuntime() {
+        return elapsedTime;
+    }
+
+    @Override
+    public Date getStartTime() {
+        return startTime;
     }
 }

Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/GenericServiceJob.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/GenericServiceJob.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/GenericServiceJob.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/GenericServiceJob.java Thu Oct 25 05:04:09 2012
@@ -18,8 +18,10 @@
  *******************************************************************************/
 package org.ofbiz.service.job;
 
+import java.io.Serializable;
 import java.util.Map;
 
+import org.ofbiz.base.util.Assert;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericRequester;
@@ -27,34 +29,25 @@ import org.ofbiz.service.LocalDispatcher
 import org.ofbiz.service.ServiceUtil;
 
 /**
- * Generic Service Job - A generic async-service Job.
+ * A generic async-service job.
  */
 @SuppressWarnings("serial")
-public class GenericServiceJob extends AbstractJob {
+public class GenericServiceJob extends AbstractJob implements Serializable {
 
     public static final String module = GenericServiceJob.class.getName();
 
-    protected transient GenericRequester requester = null;
-    protected transient DispatchContext dctx = null;
-
-    private String service = null;
-    private Map<String, Object> context = null;
+    protected final transient GenericRequester requester;
+    protected final transient DispatchContext dctx;
+    private final String service;
+    private final Map<String, Object> context;
 
     public GenericServiceJob(DispatchContext dctx, String jobId, String jobName, String service, Map<String, Object> context, GenericRequester req) {
         super(jobId, jobName);
+        Assert.notNull("dctx", dctx);
         this.dctx = dctx;
         this.service = service;
         this.context = context;
         this.requester = req;
-        runtime = System.currentTimeMillis();
-    }
-
-    protected GenericServiceJob(String jobId, String jobName) {
-        super(jobId, jobName);
-        this.dctx = null;
-        this.requester = null;
-        this.service = null;
-        this.context = null;
     }
 
     /**
@@ -62,36 +55,37 @@ public class GenericServiceJob extends A
      */
     @Override
     public void exec() throws InvalidJobException {
+        if (currentState != State.QUEUED) {
+            throw new InvalidJobException("Illegal state change");
+        }
+        currentState = State.RUNNING;
         init();
-
+        Throwable thrown = null;
         Map<String, Object> result = null;
         // no transaction is necessary since runSync handles this
         try {
             // get the dispatcher and invoke the service via runSync -- will run all ECAs
             LocalDispatcher dispatcher = dctx.getDispatcher();
             result = dispatcher.runSync(getServiceName(), getContext());
-
             // check for a failure
             if (ServiceUtil.isError(result)) {
-                 this.failed(new Exception(ServiceUtil.getErrorMessage(result)));
+                thrown = new Exception(ServiceUtil.getErrorMessage(result));
             }
-
             if (requester != null) {
                 requester.receiveResult(result);
             }
-
         } catch (Throwable t) {
-            // pass the exception back to the requester.
             if (requester != null) {
+                // pass the exception back to the requester.
                 requester.receiveThrowable(t);
             }
-
-            // call the failed method
-            this.failed(t);
+            thrown = t;
+        }
+        if (thrown == null) {
+            finish(result);
+        } else {
+            failed(thrown);
         }
-
-        // call the finish method
-        this.finish(result);
     }
 
     /**
@@ -102,11 +96,14 @@ public class GenericServiceJob extends A
     }
 
     /**
-     * Method is called after the service has finished.
+     * Method is called after the service has finished successfully.
      */
     protected void finish(Map<String, Object> result) throws InvalidJobException {
+        if (currentState != State.RUNNING) {
+            throw new InvalidJobException("Illegal state change");
+        }
+        currentState = State.FINISHED;
         if (Debug.verboseOn()) Debug.logVerbose("Async-Service finished.", module);
-        runtime = 0;
     }
 
     /**
@@ -114,8 +111,11 @@ public class GenericServiceJob extends A
      * @param t Throwable
      */
     protected void failed(Throwable t) throws InvalidJobException {
+        if (currentState != State.RUNNING) {
+            throw new InvalidJobException("Illegal state change");
+        }
+        currentState = State.FAILED;
         Debug.logError(t, "Async-Service failed.", module);
-        runtime = 0;
     }
 
     /**
@@ -130,7 +130,18 @@ public class GenericServiceJob extends A
      * Gets the name of the service as defined in the definition file.
      * @return The name of the service to be invoked.
      */
-    protected String getServiceName() throws InvalidJobException {
+    protected String getServiceName() {
         return service;
     }
+
+    @Override
+    public boolean isValid() {
+        return currentState == State.CREATED;
+    }
+
+    @Override
+    public void deQueue() throws InvalidJobException {
+        super.deQueue();
+        throw new InvalidJobException("Unable to queue job [" + getJobId() + "]");
+    }
 }

Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/Job.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/Job.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/Job.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/Job.java Thu Oct 25 05:04:09 2012
@@ -18,41 +18,59 @@
  *******************************************************************************/
 package org.ofbiz.service.job;
 
-import java.io.Serializable;
+import java.util.Date;
 
 /**
- * Job Interface
+ * A scheduled job.
+ * <p>A job starts out in the created state. When the job is queued for execution, it
+ * transitions to the queued state. While the job is executing it is in the running state.
+ * When the job execution ends, it transitions to the finished or failed state - depending
+ * on the outcome of the task that was performed.</p>
  */
-public interface Job extends Serializable {
+public interface Job extends Runnable {
+
+    public static enum State {CREATED, QUEUED, RUNNING, FINISHED, FAILED};
 
     /**
-     *  Executes the Job.
+     * Returns the current state of this job.
      */
-    public void exec() throws InvalidJobException;
+    State currentState();
 
     /**
      * Returns the ID of this Job.
      */
-    public String getJobId();
+    String getJobId();
 
     /**
      * Returns the name of this Job.
      */
-    public String getJobName();
+    String getJobName();
+
+    /**
+     *  Returns the job execution time in milliseconds.
+     *  Returns zero if the job has not run.
+     */
+    long getRuntime();
+
+    /**
+     * Returns true if this job is ready to be queued.
+     */
+    boolean isValid();
 
     /**
-     *  Returns the time to run in milliseconds.
+     * Transitions this job to the pre-queued (created) state. The job manager
+     * will call this method when there was a problem adding this job to the queue.
      */
-    public long getRuntime();
+    void deQueue() throws InvalidJobException;
 
     /**
-     * Returns true if this job is still valid.
+     * Transitions this job to the queued state.
      */
-    public boolean isValid();
+    void queue() throws InvalidJobException;
 
     /**
-     * Flags this job as 'is-queued'
+     * Returns the time this job is scheduled to start.
      */
-    public void queue() throws InvalidJobException;
+    Date getStartTime();
 }
 

Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobManager.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobManager.java?rev=1401975&r1=1401974&r2=1401975&view=diff
==============================================================================
--- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobManager.java (original)
+++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobManager.java Thu Oct 25 05:04:09 2012
@@ -20,14 +20,13 @@ package org.ofbiz.service.job;
 
 import java.io.IOException;
 import java.sql.Timestamp;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.RejectedExecutionException;
 
-import javolution.util.FastList;
-
 import org.ofbiz.base.util.Assert;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilDateTime;
@@ -38,13 +37,13 @@ import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityCondition;
-import org.ofbiz.entity.condition.EntityConditionList;
 import org.ofbiz.entity.condition.EntityExpr;
 import org.ofbiz.entity.condition.EntityOperator;
 import org.ofbiz.entity.serialize.SerializeException;
 import org.ofbiz.entity.serialize.XmlSerializer;
 import org.ofbiz.entity.transaction.GenericTransactionException;
 import org.ofbiz.entity.transaction.TransactionUtil;
+import org.ofbiz.entity.util.EntityListIterator;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ServiceContainer;
@@ -52,14 +51,22 @@ import org.ofbiz.service.calendar.Recurr
 import org.ofbiz.service.calendar.RecurrenceInfoException;
 import org.ofbiz.service.config.ServiceConfigUtil;
 
+import com.ibm.icu.util.Calendar;
+
 /**
- * JobManager
+ * Job manager. The job manager queues and manages jobs. Client code can queue a job to be run immediately
+ * by calling the {@link #runJob(Job)} method, or schedule a job to be run later by calling the
+ * {@link #schedule(String, String, String, Map, long, int, int, int, long, int)} method.
+ * Scheduled jobs are persisted in the JobSandbox entity.
+ * <p>A scheduled job's start time is an approximation - the actual start time will depend
+ * on the job manager/job poller configuration (poll interval) and the load on the server.
+ * Scheduled jobs might be rescheduled if the server is busy. Therefore, applications
+ * requiring a precise job start time should use a different mechanism to schedule the job.</p>
  */
 public final class JobManager {
 
     public static final String module = JobManager.class.getName();
     public static final String instanceId = UtilProperties.getPropertyValue("general.properties", "unique.instanceId", "ofbiz0");
-    public static final Map<String, Object> updateFields = UtilMisc.<String, Object>toMap("runByInstanceId", instanceId, "statusId", "SERVICE_QUEUED");
     private static final ConcurrentHashMap<String, JobManager> registeredManagers = new ConcurrentHashMap<String, JobManager>();
     private static boolean isShutDown = false;
 
@@ -69,68 +76,41 @@ public final class JobManager {
         }
     }
 
+    /**
+     * Returns a <code>JobManager</code> instance.
+     * @param delegator
+     * @param enablePoller Enables polling of the JobSandbox entity.
+     * @throws IllegalStateException if the Job Manager is shut down.
+     */
     public static JobManager getInstance(Delegator delegator, boolean enablePoller) {
         assertIsRunning();
         Assert.notNull("delegator", delegator);
-        JobManager jm = JobManager.registeredManagers.get(delegator.getDelegatorName());
+        JobManager jm = registeredManagers.get(delegator.getDelegatorName());
         if (jm == null) {
             jm = new JobManager(delegator);
-            JobManager.registeredManagers.putIfAbsent(delegator.getDelegatorName(), jm);
-            jm = JobManager.registeredManagers.get(delegator.getDelegatorName());
+            registeredManagers.putIfAbsent(delegator.getDelegatorName(), jm);
+            jm = registeredManagers.get(delegator.getDelegatorName());
             if (enablePoller) {
-                jm.enablePoller();
+                jm.reloadCrashedJobs();
+                JobPoller.registerJobManager(jm);
             }
         }
         return jm;
     }
 
-    /** gets the recurrence info object for a job. */
-    public static RecurrenceInfo getRecurrenceInfo(GenericValue job) {
-        try {
-            if (job != null && !UtilValidate.isEmpty(job.getString("recurrenceInfoId"))) {
-                if (job.get("cancelDateTime") != null) {
-                    // cancel has been flagged, no more recurrence
-                    return null;
-                }
-                GenericValue ri = job.getRelatedOne("RecurrenceInfo", false);
-                if (ri != null) {
-                    return new RecurrenceInfo(ri);
-                } else {
-                    return null;
-                }
-            } else {
-                return null;
-            }
-        } catch (GenericEntityException e) {
-            Debug.logError(e, "Problem getting RecurrenceInfo entity from JobSandbox", module);
-        } catch (RecurrenceInfoException re) {
-            Debug.logError(re, "Problem creating RecurrenceInfo instance: " + re.getMessage(), module);
-        }
-        return null;
-    }
-
+    /**
+     * Shuts down all job managers. This method is called when OFBiz shuts down.
+     */
     public static void shutDown() {
         isShutDown = true;
-        for (JobManager jm : registeredManagers.values()) {
-            jm.shutdown();
-        }
+        JobPoller.getInstance().stop();
     }
 
     private final Delegator delegator;
-    private final JobPoller jp;
-    private boolean pollerEnabled = false;
+    private boolean crashedJobsReloaded = false;
 
     private JobManager(Delegator delegator) {
         this.delegator = delegator;
-        jp = new JobPoller(this);
-    }
-
-    private synchronized void enablePoller() {
-        if (!pollerEnabled) {
-            pollerEnabled = true;
-            reloadCrashedJobs();
-            jp.enable();
-        }
     }
 
     /** Returns the Delegator. */
@@ -150,18 +130,30 @@ public final class JobManager {
      * @return List containing a Map of each thread's state.
      */
     public Map<String, Object> getPoolState() {
-        return jp.getPoolState();
+        return JobPoller.getInstance().getPoolState();
     }
 
-    public synchronized List<Job> poll() {
+    /**
+     * Scans the JobSandbox entity and returns a list of jobs that are due to run.
+     * Returns an empty list if there are no jobs due to run.
+     * This method is called by the {@link JobPoller} polling thread.
+     */
+    protected List<Job> poll(int limit) {
         assertIsRunning();
-        List<Job> poll = FastList.newInstance();
-        // sort the results by time
-        List<String> order = UtilMisc.toList("runTime");
+        // The rest of this method logs exceptions and does not throw them.
+        // The idea is to keep the JobPoller working even when a database
+        // connection is not available (possible on a saturated server).
+        List<Job> poll = new ArrayList<Job>(limit);
+        DispatchContext dctx = getDispatcher().getDispatchContext();
+        if (dctx == null) {
+            Debug.logWarning("Unable to locate DispatchContext object; not running job!", module);
+            return poll;
+        }
         // basic query
         List<EntityExpr> expressions = UtilMisc.toList(EntityCondition.makeCondition("runTime", EntityOperator.LESS_THAN_EQUAL_TO, UtilDateTime.nowTimestamp()),
-                EntityCondition.makeCondition("startDateTime", EntityOperator.EQUALS, null), EntityCondition.makeCondition("cancelDateTime",
-                EntityOperator.EQUALS, null), EntityCondition.makeCondition("runByInstanceId", EntityOperator.EQUALS, null));
+                EntityCondition.makeCondition("startDateTime", EntityOperator.EQUALS, null),
+                EntityCondition.makeCondition("cancelDateTime", EntityOperator.EQUALS, null),
+                EntityCondition.makeCondition("runByInstanceId", EntityOperator.EQUALS, null));
         // limit to just defined pools
         List<String> pools = ServiceConfigUtil.getRunPools();
         List<EntityExpr> poolsExpr = UtilMisc.toList(EntityCondition.makeCondition("poolId", EntityOperator.EQUALS, null));
@@ -174,81 +166,126 @@ public final class JobManager {
         EntityCondition baseCondition = EntityCondition.makeCondition(expressions);
         EntityCondition poolCondition = EntityCondition.makeCondition(poolsExpr, EntityOperator.OR);
         EntityCondition mainCondition = EntityCondition.makeCondition(UtilMisc.toList(baseCondition, poolCondition));
-        // we will loop until we have no more to do
-        boolean pollDone = false;
-        while (!pollDone) {
-            boolean beganTransaction = false;
+        EntityListIterator jobsIterator = null;
+        boolean beganTransaction = false;
+        try {
+            beganTransaction = TransactionUtil.begin();
+            if (!beganTransaction) {
+                Debug.logWarning("Unable to poll JobSandbox for jobs; transaction was not started by this process", module);
+                return poll;
+            }
+            jobsIterator = delegator.find("JobSandbox", mainCondition, null, null, UtilMisc.toList("runTime"), null);
+            GenericValue jobValue = jobsIterator.next();
+            while (jobValue != null) {
+                // Claim ownership of this value. Using storeByCondition to avoid a race condition.
+                List<EntityExpr> updateExpression = UtilMisc.toList(EntityCondition.makeCondition("jobId", EntityOperator.EQUALS, jobValue.get("jobId")), EntityCondition.makeCondition("runByInstanceId", EntityOperator.EQUALS, null));
+                int rowsUpdated = delegator.storeByCondition("JobSandbox", UtilMisc.toMap("runByInstanceId", instanceId), EntityCondition.makeCondition(updateExpression));
+                if (rowsUpdated == 1) {
+                    poll.add(new PersistedServiceJob(dctx, jobValue, null));
+                    if (poll.size() == limit) {
+                        break;
+                    }
+                }
+                jobValue = jobsIterator.next();
+            }
+        } catch (Throwable t) {
+            poll.clear();
+            String errMsg =  "Exception thrown while polling JobSandbox: ";
+            Debug.logWarning(t, errMsg, module);
+            try {
+                TransactionUtil.rollback(beganTransaction, errMsg + t.getMessage(), t);
+            } catch (GenericEntityException e) {
+                Debug.logWarning(e, "Exception thrown while rolling back transaction: ", module);
+            }
+        } finally {
+            if (jobsIterator != null) {
+                try {
+                    jobsIterator.close();
+                } catch (GenericEntityException e) {
+                    Debug.logWarning(e, module);
+                }
+            }
+            try {
+                TransactionUtil.commit(beganTransaction);
+            } catch (GenericTransactionException e) {
+                Debug.logWarning(e, "Transaction error trying to commit when polling and updating the JobSandbox: ", module);
+            }
+        }
+        if (poll.isEmpty()) {
+            // No jobs to run, see if there are any jobs to purge
+            int daysToKeep = ServiceConfigUtil.getPurgeJobDays();
+            Calendar cal = Calendar.getInstance();
+            cal.add(Calendar.DAY_OF_YEAR, -daysToKeep);
+            Timestamp purgeTime = new Timestamp(cal.getTimeInMillis());
+            List<EntityExpr> finExp = UtilMisc.toList(EntityCondition.makeCondition("finishDateTime", EntityOperator.NOT_EQUAL, null), EntityCondition.makeCondition("finishDateTime", EntityOperator.LESS_THAN, purgeTime));
+            List<EntityExpr> canExp = UtilMisc.toList(EntityCondition.makeCondition("cancelDateTime", EntityOperator.NOT_EQUAL, null), EntityCondition.makeCondition("cancelDateTime", EntityOperator.LESS_THAN, purgeTime));
+            EntityCondition doneCond = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition(canExp), EntityCondition.makeCondition(finExp)), EntityOperator.OR);
+            mainCondition = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("runByInstanceId", instanceId), doneCond));
+            beganTransaction = false;
+            jobsIterator = null;
             try {
                 beganTransaction = TransactionUtil.begin();
                 if (!beganTransaction) {
-                    Debug.logError("Unable to poll for jobs; transaction was not started by this process", module);
-                    return null;
+                    Debug.logWarning("Unable to poll JobSandbox for jobs; transaction was not started by this process", module);
+                    return poll;
                 }
-                List<Job> localPoll = FastList.newInstance();
-                // first update the jobs w/ this instance running information
-                delegator.storeByCondition("JobSandbox", updateFields, mainCondition);
-                // now query all the 'queued' jobs for this instance
-                List<GenericValue> jobEnt = delegator.findByAnd("JobSandbox", updateFields, order, false);
-                // jobEnt = delegator.findByCondition("JobSandbox", mainCondition, null, order);
-                if (UtilValidate.isNotEmpty(jobEnt)) {
-                    for (GenericValue v : jobEnt) {
-                        DispatchContext dctx = getDispatcher().getDispatchContext();
-                        if (dctx == null) {
-                            Debug.logError("Unable to locate DispatchContext object; not running job!", module);
-                            continue;
-                        }
-                        Job job = new PersistedServiceJob(dctx, v, null); // TODO fix the requester
-                        try {
-                            job.queue();
-                            localPoll.add(job);
-                        } catch (InvalidJobException e) {
-                            Debug.logError(e, module);
-                        }
+                jobsIterator = delegator.find("JobSandbox", mainCondition, null, null, UtilMisc.toList("jobId"), null);
+                GenericValue jobValue = jobsIterator.next();
+                while (jobValue != null) {
+                    poll.add(new PurgeJob(jobValue));
+                    if (poll.size() == limit) {
+                        break;
                     }
-                } else {
-                    pollDone = true;
+                    jobValue = jobsIterator.next();
                 }
-                // nothing should go wrong at this point, so add to the general list
-                poll.addAll(localPoll);
             } catch (Throwable t) {
-                // catch Throwable so nothing slips through the cracks... this is a fairly sensitive operation
-                String errMsg = "Error in polling JobSandbox: [" + t.toString() + "]. Rolling back transaction.";
-                Debug.logError(t, errMsg, module);
+                poll.clear();
+                String errMsg =  "Exception thrown while polling JobSandbox: ";
+                Debug.logWarning(t, errMsg, module);
                 try {
-                    // only rollback the transaction if we started one...
-                    TransactionUtil.rollback(beganTransaction, errMsg, t);
-                } catch (GenericEntityException e2) {
-                    Debug.logError(e2, "[Delegator] Could not rollback transaction: " + e2.toString(), module);
+                    TransactionUtil.rollback(beganTransaction, errMsg + t.getMessage(), t);
+                } catch (GenericEntityException e) {
+                    Debug.logWarning(e, "Exception thrown while rolling back transaction: ", module);
                 }
             } finally {
+                if (jobsIterator != null) {
+                    try {
+                        jobsIterator.close();
+                    } catch (GenericEntityException e) {
+                        Debug.logWarning(e, module);
+                    }
+                }
                 try {
-                    // only commit the transaction if we started one... but make sure we try
                     TransactionUtil.commit(beganTransaction);
                 } catch (GenericTransactionException e) {
-                    String errMsg = "Transaction error trying to commit when polling and updating the JobSandbox: " + e.toString();
-                    // we don't really want to do anything different, so just log and move on
-                    Debug.logError(e, errMsg, module);
+                    Debug.logWarning(e, "Transaction error trying to commit when polling the JobSandbox: ", module);
                 }
             }
         }
         return poll;
     }
 
-    private void reloadCrashedJobs() {
+    private synchronized void reloadCrashedJobs() {
+        assertIsRunning();
+        if (crashedJobsReloaded) {
+            return;
+        }
         List<GenericValue> crashed = null;
-        List<EntityExpr> exprs = UtilMisc.toList(EntityCondition.makeCondition("runByInstanceId", instanceId));
-        exprs.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "SERVICE_RUNNING"));
-        EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(exprs);
+        List<EntityExpr> statusExprList = UtilMisc.toList(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "SERVICE_PENDING"),
+                EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "SERVICE_QUEUED"),
+                EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "SERVICE_RUNNING"));
+        EntityCondition statusCondition = EntityCondition.makeCondition(statusExprList, EntityOperator.OR);
+        EntityCondition mainCondition = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("runByInstanceId", instanceId), statusCondition));
         try {
-            crashed = delegator.findList("JobSandbox", ecl, null, UtilMisc.toList("startDateTime"), null, false);
+            crashed = delegator.findList("JobSandbox", mainCondition, null, UtilMisc.toList("startDateTime"), null, false);
         } catch (GenericEntityException e) {
-            Debug.logError(e, "Unable to load crashed jobs", module);
+            Debug.logWarning(e, "Unable to load crashed jobs", module);
         }
         if (UtilValidate.isNotEmpty(crashed)) {
-            try {
-                int rescheduled = 0;
-                for (GenericValue job : crashed) {
-                    Timestamp now = UtilDateTime.nowTimestamp();
+            int rescheduled = 0;
+            Timestamp now = UtilDateTime.nowTimestamp();
+            for (GenericValue job : crashed) {
+                try {
                     Debug.logInfo("Scheduling Job : " + job, module);
                     String pJobId = job.getString("parentJobId");
                     if (pJobId == null) {
@@ -267,16 +304,17 @@ public final class JobManager {
                     job.set("cancelDateTime", now);
                     delegator.store(job);
                     rescheduled++;
+                } catch (GenericEntityException e) {
+                    Debug.logWarning(e, module);
                 }
-                if (Debug.infoOn())
-                    Debug.logInfo("-- " + rescheduled + " jobs re-scheduled", module);
-            } catch (GenericEntityException e) {
-                Debug.logError(e, module);
             }
+            if (Debug.infoOn())
+                Debug.logInfo("-- " + rescheduled + " jobs re-scheduled", module);
         } else {
             if (Debug.infoOn())
                 Debug.logInfo("No crashed jobs to re-schedule", module);
         }
+        crashedJobsReloaded = true;
     }
 
     /** Queues a Job to run now.
@@ -286,7 +324,7 @@ public final class JobManager {
     public void runJob(Job job) throws JobManagerException {
         assertIsRunning();
         if (job.isValid()) {
-            jp.queueNow(job);
+            JobPoller.getInstance().queueNow(job);
         }
     }
 
@@ -501,13 +539,4 @@ public final class JobManager {
             throw new JobManagerException(e.getMessage(), e);
         }
     }
-
-    /** Close out the scheduler thread. */
-    public void shutdown() {
-        Debug.logInfo("Stopping the JobManager...", module);
-        registeredManagers.remove(delegator.getDelegatorName(), this);
-        jp.stop();
-        Debug.logInfo("JobManager stopped.", module);
-    }
-
 }