Translate

Saturday, December 1, 2012

Windows 8, 32 bit Install

Installed Windows 8 32 bit on a solid state drive in my Pentium 4 desktop. There were a few issues I ran into with the install, mainly because the system doesn't have a DVD player. What I had to do is put the drive in my laptop and install it there, and then put the drive back in the desktop. It worked but wouldn't recognize my desktop's USB network adapter, an old Linksys WUSB54G! So I put the drive back in my laptop where the internal network adapter worked just fine and I connected to my home network. Then I plugged in the Linksysadapter and Windows detected it and downloaded and installed the driver. I put the drive back in my desktop and I'm up and running and connected to the Internet! Once the Linksys was working I was also able to get an Alfa AWUS036H and a Netgear WNDA3100 running! When I connected each adapter, Windows 8 detected and installed the new device!

Friday, November 9, 2012

jQuery - DataTables Server-side Sorting

I couldn't use the server-side sorting ability of DataTables and needed to implement my own. Here's how I did it:

First - turn off DataTables sorting by setting bSort to false.

2 - Add a hidden Div for the menu for my sorting:


<div id="tabmenu" style="visibility: hidden; display: none; position: absolute; z-index: 6" class="popTableMenu">
 <table cellspacing="0" cellpadding="0">
   <tr>
     <td>
       <a id="fpopSortDn" href="#" onclick="return inSort('asc')">Sort down</a>
       <a id="fpopSortUp" href="#" onclick="return inSort('desc')">Sort up</a>    
     </td>
   </tr>
 </table>
</div>


3 - Modify the column heading, adding "onmouseover" and "onclick" events:

<th style="height:26px;" class="heading" onmouseover="inMenuHide()" onclick="inMenuShow(this, '${fieldName}');" ><s:property value="fieldLabel"/></th>


4 - Add the JavaScript to handle the mouse events:

<script type="text/javascript"<
var tSort;

function inSort(direct){
 inMenuHide();
 showLoading();
 var mID = $('#${tablename}viewID').val();
 var mAct = $('#${tablename}listActionName').val();
 $('div#divBody').load('/InForm${namespace}/'+mAct+'.action?rpp=' + $('#resPerPage').val() + '&sortBy=' + tSort + '&sortOrder=' + direct + '&viewID=' + mID + '&search=' + $('#${tablename}fastSearch').val());
 return false;
}

function inMenuShow(cell, field){
 tSort = field;
 var offset = $(cell).offset();
 var cH = $(cell).height();
 var pT = offset.top + cH;
 $("#tabmenu").offset({ top: pT, left: offset.left });
 $('#tabmenu').css("visibility","visible");
 $("#tabmenu").show("fast");
}

function inMenuHide(){
 $("#tabmenu").offset({ top: 0, left: 0 });
 $("#tabmenu").hide();
 $('#tabmenu').css("visibility","hidden");
}
</script>

Clicking on a column heading will call "inMenuShow" so that the sort memu, the hidden Div, displays below the column:
Clicking on an item in the sort menu wil call the "inSort" method. This method calls my struts action and populates the table container, "divBody", with the returned page. The page that's returned ids the sorted table.

Friday, November 2, 2012

Java - Missing User When Querying Active Directory

In an application that I'm working on I'm using the "DirContext" to query Active Directory for users and permissions. A new user wasn't showing up in the query results. It turned out that since I was filtering my search on the City and he was set up without having an entry for City he wouldn't be returned in the search.

Friday, October 26, 2012

jQuery - Append an Image and Handle the Click Event

In a web application that I developed I was asked to modify the contents of on input tag when a buttom was clicked. Since the application was designed to use the same JSP page for all table edits I didn't want to create a custom JSP page for this table. So I added the button using jQuery.

Here is the JSP for the page:

<jsp:include page="../genBase/recordEdit.jsp" />
<script>
$(document).ready(function(){ 
$('#dispurlLinkToFile').after(' <img title="Generate URL location" id="imgUrlLinkToFile" style="border-top-color: currentColor; border-right-color: currentColor; border-bottom-color: currentColor; border-left-color: currentColor; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none;" alt="Generate URL location" src="../images/max1t.gif"/>');
$('#imgUrlLinkToFile').click(function() {
 $('#dispurlLinkToFile').val('https://ABC.XYZ.org/ProposalDev/Proposals/'+$('#dispinternalRefNum').val().replace(/-/g,"_")+'.zip');});
});
</script>

Here's what the page is doing:
The global edit page, "recordEdit.jsp", is loaded.
The jQuery script, "$('#dispurlLinkToFile').after", is adding an icon after the input field with the id of "dispurlLinkToFile". The image tag is assigned an id of "imgUrlLinkToFile".
The jQuery script for the "imgUrlLinkToFile" click function takes the vale from the tag with the id "dispinternalRefNum", replaces "-" with "_", which gets added to "https://ABC.XYZ.org/ProposalDev/Proposals/" and written to "dispurlLinkToFile".
So we go from our original:

To the same with or image added:
Then when the button is clicked the field is populated:

Friday, October 19, 2012

SharePoint 2010 - External List Authentication

Another thing that constantly gets me - whenever you set up an secure store application and do not set it up as a group type (individual is the default) you will get the "Click here to authenticate" link on the list in SharePoint!

SQL - Table Changes and Views

One of the things that I still get hung up on is the need to update table views when I add or delete columns. The most common thing that happens is a "field not found" type of error. Then yesterday I was working in SharePoint designer and received an error that said "View or function 'XXX.dbo.vwXXX' has more column names specified than columns defined". Doing an ALTER view is SQL manager solved the problem.

Wednesday, October 10, 2012

jQuery - Posting Large Forms

I had a grid table that I was submitting that stopped submitting once the table grew. I'm using the jQuery "load" function to submit the form and return the results. It turns out that if you use the jQuery "serialize" function to serialize a form then jQuery will do a GET. Use the jQuery "serializeArray" function so that jQuery does a POST!

Monday, October 8, 2012

Tomcat - Authentication Problem With IE

I'm using the Waffle library for authentication in a web application. The authentication wouldn't work in Internet Explorer because the site is listed as one of the Intranet Sites in IE. The solution was to add the following JavaScript to the log in page:

<script type="text/javascript">
  document.domain="example.com";
</script>

SQL - Import Data

A few pointers on importing data into a SQL database.

The project that I'm currently working on required data to be imported into SQL server from a different database. Fortunately, SQL Management Studio has a nice feature for importing data. But importing data into SQL is not that strait forward. Things can go wrong depending on the type of data that your importing so it pays to spend some time looking at the data that you are going to be importing before you start.

The database that I was exporting the data from gave me three options for export; Comma Separated Values (CSV), Tab Separated Values (TSV), and XML. CSV was the one that I used the most and XML wasn't useful at all with the data that I needed to export.

My first attempt was importing the CSV file into SQL. This didn't work at all because I had a field the contained carriage returns and line feeds. Since a record is denoted by a new line you can see how this would cause a problem. Other fields like date fields could also cause problems with the import.

The next step was to open the CSV file in Excel and save it as an Excel (xls) file. In some cases this was all that I needed to do to be able to import the data into SQL.

When the Excel file wouldn't work I would import either the CSV or the Excel file into Access. The nice thing about doing the Access import is that Access will show you the records and fields where it's having a problem with the data. The Access file import into SQL usually worked but occasionally I would need to change the field type in the Access database.

The last thing that caused a problem was bogus (end of line ) characters in foreign key fields. This prevented my SQL statements from being able to match the foreign keys from the imported data with my SQL tables. They would show up as space characters and were not removable using the SQL RTIM function because they are not a space character! The fix for that was the following SQL to remove the problem characters:


Update [QuickBaseImportsv1].[dbo].[SubAgreements3]
set [Task#] = ltrim(rtrim(replace([Task#], char(160), char(32))))
Update [QuickBaseImportsv1].[dbo].[SubAgreements3]
set [Task#] = ltrim(rtrim(replace([Task#], char(10), char(32))))
Update [QuickBaseImportsv1].[dbo].[SubAgreements3]
set [Task#] = ltrim(rtrim(replace([Task#], char(13), char(32))))

One final piece of advice - unless you are dealing with a very simple table, do not try to import the data directly into your final, target SQL tables. Import the data into an intermediary table first where you can massage the data before transferring the data to your target SQL tables.

Tuesday, September 25, 2012

SharePoint 2010 - Fast Search "Failed to connect..." Error

This was just one of the many problems I had to deal with today! One of the common things that happens with a Fast Search setup is to have your self-signed certificate expire after one year. When this happens, you will get the following error in the application error log of your SharePoint server:
Failed to connect to SERVER.com:XXXX Failed to initialize session with document engine: Unable to resolve Contentdistributor

The solution is simple enough, just install a new certificate!
Here are some helpful sites:
SharePoint Malarkey
SharePoint Fanatic
FAST Forum
Microsoft
Microsoft TechNet

Friday, September 7, 2012

Struts - Include Causes BufferOverflowException

Using the Struts include tag on some pages is causing the following error:
java.nio.BufferOverflowException
at java.nio.HeapByteBuffer.put(Unknown Source)
at org.apache.struts2.util.FastByteArrayOutputStream.decodeAndWriteOut(FastByteArrayOutputStream.java:161)
at org.apache.struts2.util.FastByteArrayOutputStream.writeTo(FastByteArrayOutputStream.java:94)
at org.apache.struts2.components.Include.include(Include.java:285)
at org.apache.struts2.components.Include.end(Include.java:167)
at org.apache.struts2.views.jsp.ComponentTagSupport.doEndTag(ComponentTagSupport.java:42)
The only solution I could find so far is to replace the Struts include with a JSP include. Does anyone know how to fix this so it works in Struts?

Thursday, August 2, 2012

jQuery - Submit a Form Using an Anchor Tag

While you can use JavaScript in the onclick event of an anchor tag to submit a form, there may be times when you need to submit additional information along with the form. That's what I needed to do and this is how I did it using the jQuery method. This example is for Struts 2 but should work with a regular anchor tag.


<s:url var="urlFkey" namespace="%{namespace}" action="GotoAddForeignKeyRecord" escapeAmp="false" >
  <s:param name="target" >disp${fieldName}</s:param>
  <s:param name="fkeyName" value="fkeyName"/>
  <s:param name="fkeyTableName" value="fkeyPrimaryTableName"/>
  <s:param name="recordID" value="recordID"/>
</s:url>
<s:a id="disp%{fieldName}" href="%{urlFkey}" cssClass='nyroModal' onclick="this.href = this.href + '&' + $('#%{dispTablename}saveRecord').serialize();">
   Add New <s:property value="fkeyPrimaryTableNameLabel"/>
</s:a>

In the JSP snippet above I am calling the jQuery serialize method in the onclick event of the anchor tag and appending the returned result to the href for the tag.

Monday, July 23, 2012

Internews - Study Examines Potential of Digital Society in Indonesia

With more than 43 million Facebook accounts and 19 million active Twitter users, Indonesia boasts the second highest number of social media users in Asia. Despite the wave of new technology, these figures mask a stronger undercurrent of digital and social inequality. Indonesia: New Digital Nation?, a new report from the Internews Center for Innovation & Learning, explores the potential and limitations of social media and new ICTs to support local community development and advocacy in Indonesia. Read more.

Wednesday, July 18, 2012

jQuery - DataTables, Buttons, CSV

Another example of adding buttons in jQuery DataTables and outputing to CSV. This puts a button in the wrapper div.


$(document).ready(function() {
   $('#example').dataTable();
   $('<div />').css({'float' : 'left'}).css({'padding-right' : '20px'}).attr({'id' : 'fButtons'}).prependTo($('#example_wrapper'));
   $('<button />').attr({
      'id' : 'tabletocsv'
   })
   .html('CSV')
   .appendTo($('#fButtons'));

   $('#tabletocsv').click( function () {
    rgDataTable2CSV(0);
   });     
     
function rgDataTable2CSV(mOffset) {
  
    function row2CSV(tmpRow) {
        var tmp = tmpRow.join(''); // to remove any blank rows
        if (tmpRow.length > 0 && tmp !== '') {
            var mystr = tmpRow.join(',');
            csvData[csvData.length] = mystr;
        }
    }       
    function formatData(input) {
        // replace " with “
        var regexp = new RegExp(/["]/g);
        var output = input.replace(regexp, "“");
        //HTML
        regexp = new RegExp(/\<[^\<]+\>/g);
        output = output.replace(regexp, "");
        if (output === "") return '';
        return '"' + output + '"';
    }       
    function popup(data) {
        var generator = window.open('', 'csv', 'height=400,width=600,menubar=1,resizable=1');
        generator.document.write('<html><head><title>CSV</title>');
        generator.document.write('</head><body >');
        generator.document.write('<textArea cols=70 rows=15 wrap="off" >');
        generator.document.write(data);
        generator.document.write('</textArea>');
        generator.document.write('</body></html>');
        generator.document.close();
        generator.focus();
    }
    var csvData = [];
    var tmpRow = [];

   //get the header
   var el = $('#example').find('thead');
   (el).find('tr').each (function() {   
   tmpRow = [];   
   $(this).find('th').each(function(index, domEle) { 
   tmpRow[tmpRow.length] = formatData($.trim($(this).html()));
    });
   row2CSV(tmpRow);   });

    //get the data
   $('#example').find('tr').each (function() {   
   tmpRow = [];   
   $(this).find('td').each(function(index, domEle) {   
   tmpRow[tmpRow.length] = formatData($.trim($(this).html()));
   });
   row2CSV(tmpRow);   });
 
    var mydata = csvData.join('\n');
    return popup(mydata);

}  
     
});

You can test it out here.

Tuesday, July 17, 2012

jQuery - Add Buttons to DataTables

A simple example of adding buttons to jQuery DataTables before the search filter.


$(document).ready(function() {
   $('#example').dataTable();
     
   $('<div />').addClass('UnSelectAllButton').css({'float' : 'left'}).attr({'id' : 'UnSelectAllButtons'}).prependTo($('#example_filter'));
     
   $('<button />').attr({
      'id' : 'deSelectAll'
   })
   .html('Deselect All')
   .appendTo($('#UnSelectAllButtons'));

   $('<button />').attr({
      'id' : 'selectAll'
   })
   .html('Select All')
   .appendTo($('#UnSelectAllButtons'));

   $('#deSelectAll').click( function () {
    alert( 'Deselect all.');
   });     
     
   $('#selectAll').click( function () {
    alert( 'Select all.');
  });
     
});

You can test it out here.

Monday, July 16, 2012

jQuery - Output DataTables as CSV

I switched to using jQuery DataTables in my project and need a way to output the table data as CSV. Here is the JavaScript that I came up with:


function rgDataTable2CSV(mTable, mOffset) {
   var csvData = [];
   var tmpRow = [];
   var cL = 0;
   //get the header
   $('#lstTabHead'+ mTable + ' th').each (function(index, domEle) {
       if ($(this).closest('.dataTables_scrollHeadInner').length > 0){
          tmpRow[tmpRow.length] = formatData($.trim($(this).html()));
       };
   });
    row2CSV(tmpRow);
    //get the data
   $('#lstTab' + mTable).find('tr').each (function() {
      tmpRow = [];
      $(this).find('td').each(function(index, domEle) {
          tmpRow[tmpRow.length] = formatData($.trim($(this).html()));
        });
       row2CSV(tmpRow);
   });
    tmpRow = [];
    //this gets the left side (the fixed column)
   $('#lstTabFoot' + mTable).find('tr').each (function() {
      $(this).find('td').each(function(index, domEle) {
          tmpRow[tmpRow.length] = formatData($.trim($(this).html()));
        });
   });
   cl = 0;
   //this gets the right side
   $('#lstTabFoot'+ mTable + ' td').filter(':visible').each (function(index, domEle) {
       if ($(this).closest('.dataTables_scrollFootInner').length > 0){
          cL = cL + 1
          if(cL > mOffset){
          tmpRow[tmpRow.length] = formatData($.trim($(this).html()));
          };
       };
   });
   row2CSV(tmpRow);    
    var mydata = csvData.join('\n');
    return popup(mydata);
          
    function row2CSV(tmpRow) {
        var tmp = tmpRow.join('') // to remove any blank rows
        if (tmpRow.length > 0 && tmp != '') {
            var mystr = tmpRow.join(',');
            csvData[csvData.length] = mystr;
        }
    }
       
    function formatData(input) {
        // replace " with “
        var regexp = new RegExp(/["]/g);
        var output = input.replace(regexp, "“");
        //HTML
        var regexp = new RegExp(/\<[^\<]+\>/g);
        var output = output.replace(regexp, "");
        if (output == "") return '';
        return '"' + output + '"';
    }
       
    function popup(data) {
        var generator = window.open('', 'csv', 'height=400,width=600,menubar=1,resizable=1');
        generator.document.write('<html><head><title>CSV</title>');
        generator.document.write('</head><body >');
        generator.document.write('<textArea cols=70 rows=15 wrap="off" >');
        generator.document.write(data);
        generator.document.write('</textArea>');
        generator.document.write('</body></html>');
        generator.document.close();
        generator.focus();
    }
       
}


This script is based off of the Table2CSV script. The HTML table structure for the of the DataTables in my application have a thead id = lstTabHead + tablename, tbody id = lstTab + tablename, tfoot id = lstTabFoot + tablename. This naming convention is required by this script. Call the script using "rgDataTable2CSV(tablename, 1)". The second parameter is an offset that is used for the first column being omitted.

Friday, July 13, 2012

Windows 7 - Would Not Start

Restarted my laptop yesterday morning and it could not start Windows. Here's how I fixed it.

I tried booting into safe mode but it got stuck at loading "Classpnp.sys".

I put my Windows 7 DVD in the drive and booted from the DVD. After it installed it's files and I got to the install screen I selected repair in the lower left corner. It ran saying it was searching for installs even though it listed my install. I finally had to power it off after two hours because it wasn't getting anywhere.

It was clear I wasn't going to get anywhere on my laptop so I took the hard drive out and attached it externally to another computer. The drive showed up OK so I ran "CHKDSK" on it. When "CHKDSK" finished I put the drive back into my laptop.

Back on my laptop I booted from the DVD and ran repair. This time it was able to find my install! It took about a half hour to run but eventually the repair finished.

I booted into Windows and I was able to log in. The start-up was really slow and not getting anywhere fast so I powered off the laptop and started Windows in safe mode.

The laptop booted into safe mode just fine. I opened a command prompt as administrator and ran "sfc /scannow". It finished and the message said that there were some files it was not able to repair.

I restarted the laptop and booted into Windows. This time it started up just fine! I checked the hard drive and noticed I had almost double the free space that I had when I last looked at it a couple of days ago. Obviously there are some files were corrupted. So far everything is working OK but I do realize that this hard drive cannot be trusted and I need to get a new hard drive.

Wednesday, July 11, 2012

jQuery - DataTables Plug-in

Received a request to have the tables sortable in the the web application that I'm working on. I looked around a bit to see what was available and decided to give DataTables a try. The first column in my table is fixed and contains links to actions (view and edit) so I'm using the FixedColumns plugin to hold the column in place while the remainder of the table is scrollable both horizontally and vertically.

So far it's been working very nicely but there were a couple of issues. The FixedColumns plugin wasn't setting the column width correctly for an empty table. That was fixed by setting the "iLeftWidth" property. I also needed to set it so that the first column could not sortable on. I found that the simplest way to do that was to use the "aoColumnDefs" property.

Here is my initialization script:

$(document).ready( function () {
 var oTable = $('#tableID').dataTable( {
 "aaSorting": [ [1, "asc"] ],
 "sScrollY": "600px",
 "sScrollX": "100%",
 "bScrollCollapse": true,
 "bStateSave": true,
 "bPaginate": false,
//make first column not sortable
 "aoColumnDefs": [{"bSortable": false, "aTargets": [0]}] 
 });
 new FixedColumns( oTable, {
   "iLeftWidth": "100"
 });
});

So far I'm very impressed by what this jQuery plug-in can do. I have noticed that the page load times have increase. Waiting to see if this will be an issue for the end users.

Monday, July 9, 2012

jQuery - Convert HTML Table to Excel

One of my users needs to be able to save table data as an Excel file in the web app that I'm working on and the web app is just weeks from being released. Luckily it's easy to do this using the jQuery table2CSV plugin. It seems there are a few of these floating around the Internet. I got mine from the jQuery tableToCSV plugin site. Works like a charm. The only thing I need to fix was:

Change this:
if ($(this).css('display') != 'none') tmpRow[tmpRow.length] = formatData($(this).html());
To this:
if ($(this).css('display') != 'none') tmpRow[tmpRow.length] = formatData($.trim($(this).html()));

Thursday, June 28, 2012

jQuery - Multiple Subscriptions to a Topic

The other thing that caught me a couple of times this past month were multiple subscriptions to a topic when using subscribe. This was causing my AJAX action to be called multiple times. It turns out that if you do this:

$.subscribe('Whatever}', function(event,data) {...
in the page that you are returning using AJAX, the subscribe is saved. So the next time you make the same AJAX request and return with the page you will have another subscription to the topic.
What you need to do is specify the id of the tag like this this:

$('#TheID').subscribe('Whatever', function(event,data) {...

AJAX - Prevent Page Caching

There were a couple of little things that caught me this past. The first one was how Internet Explorer is so aggressive about caching and it's really annoying when it caches AJAX results. I decided to deal with it in my Struts action by adding a header to my response like this:

this.response.addHeader("Cache-Control", "max-age=0,no-cache,no-store,post-check=0,pre-check=0");

Monday, June 25, 2012

Internews - InfoAmazonia Launched: The Amazon as You’ve Never Seen It

Internews and O Eco, a Brazilian environmental news agency, have launched a pioneering new website. InfoAmazonia.org is an interactive mapping platform that provides timely news and reports of environmental challenges in the Amazon region through an innovative visualization of data. More...

Friday, June 15, 2012

AJAX - Browser History

One of the issues with using AJAX in a web site is that the browser history does not work. I spent a few days trying out quite a few of the solutions that you can find on the web and I was unable to find one that worked consistently in my application. The only option left was to add my own history and back button to my application.

The script file, rgUrlHistory.js:

var rgUrlStack = new Array();
var rgIdx = 0;

function rgPushAction(mAct, mApp, mID, mType) {
  rgObj = [];
  rgObj.action = mAct;
  rgObj.appID = mApp;
  rgObj.type = mType;
  rgObj.id = mID;
  rgUrlStack.push(rgObj);
  //limit to 10 items
  if (rgUrlStack.length > 10) rgUrlStack.splice(0,1); 
  rgIdx = rgUrlStack.length;
}

function rgBackAction() {
  var rgPop;
  //if we are at the top of the stack we need to pop this value because the first value popped is the current URL
  if (rgUrlStack.length == rgIdx) rgUrlStack.pop();
  //if we still have a value, pop it
  if(rgUrlStack.length > 0){
    rgPop = rgUrlStack.pop();
    //always keep one value on the stack
    if(rgUrlStack.length == 0) rgUrlStack.push(rgPop);
  }
  return rgPop;
}


In my application I call rgPushAction to save my URL and some additional information:

onclick="rgPushAction('%{urlFkey}','%{appTableID}','%{ID}','%{currentAppTable.type}');

On the menu bar in my web application I added a left arrow icon and call the the following JavaScript when the image is clicked:

function runBackQuery(){
   $.publish('HideViewMenu');
   var rgObj = rgBackAction();
   if(rgObj != ""){
     listView(rgObj.type, rgObj.appID, rgObj.id)
     $.post(rgObj.action, function(result){
          $("div#divBody").html(result);
        });
     $.publish('ShowDivBody');
   }
}

This script uses jQuery post with the URL we saved returned in rgObj.action to populate our target Div tag, divBody. "listView" is just another function that is called with the additional information we saved in the rgObj object. That's all there is to doing your own browser history for your AJAX actions.

Tuesday, May 29, 2012

Internews - Learn to Communicate with Crisis-Affected Communities

A new, free online learning course, Communication is Aid, aims to raise awareness and build basic skills for communicating effectively with crisis-affected communities, before and after an emergency breaks.

Read the rest of the story here.

Wednesday, May 23, 2012

Internews - Armenian Media Pioneer Hopes to Engage the Public through Citizen Reporting Gaming Platform

In October 2010, Armenian schoolchildren documented numerous cases of physical abuse at the hands of teachers using the cameras on their mobile phones. However, as Armenian journalist Seda Muradyan noted in her 2011 Knight Fellowship presentation at Stanford University, few people saw the videos until six months or even a year after they were shot, when they were uploaded online and swiftly went viral.

Read the rest of the story here.

Monday, May 21, 2012

Java - Calculate Date Frequency

I needed to calculate the biweekly, monthly, or quarterly date frequency and create a list of dates. It's easy using Joda Time.


Here is my Java class. Just pass the start date and end date to the method.

package org.inewsnet.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.joda.time.LocalDate;
import org.joda.time.Period;

/**
 * Methods to calculate biweekly, monthly, and quarterly date  frequencies
 * @author Richard Golebiowski
 *
 */
public class DateTimeService {
    /**
     * Calculates the dates for the Biweekly frequency
     * @param dtStart  the tart date
     * @param dtEnd    the end date
     * @return         a list of dates
     */
    public List<Date> getBiwekly(Date dtStart, Date dtEnd){
        List <Date> lstDate = new ArrayList<Date>();
        LocalDate start = new LocalDate(dtStart);
        LocalDate end = new LocalDate(dtEnd);
        Period period = Period.weeks(2);
        Period current = Period.ZERO;
        while (true) {
            LocalDate candidate = start.plus(current);
            if (candidate.isEqual(end) || candidate.isAfter(end)) {
                lstDate.add(dtEnd); 
                return lstDate;
            }
            else {
                lstDate.add(candidate.toDate());      
            }
            current = current.plus(period);
        }
    }
    
    /**
     * Calculates the dates for the Monthly frequency
     * @param dtStart  the tart date
     * @param dtEnd    the end date
     * @return         a list of dates
     */
    public List<Date> getMonthly(Date dtStart, Date dtEnd){
        List <Date> lstDate = new ArrayList<Date>();
        LocalDate start = new LocalDate(dtStart);
        LocalDate end = new LocalDate(dtEnd);
        Period period = Period.months(1);
        Period current = Period.ZERO;
        while (true) {
            LocalDate candidate = start.plus(current);
            if (candidate.isEqual(end) || candidate.isAfter(end)) {
                lstDate.add(dtEnd); 
                return lstDate;
            }
            else {
                lstDate.add(candidate.toDate());                
            }
            current = current.plus(period);
        }
    }

    /**
     * Calculates the dates for the Quarterly frequency
     * @param dtStart  the tart date
     * @param dtEnd    the end date
     * @return         a list of dates
     */
    public List<Date> getQuarterly(Date dtStart, Date dtEnd){
        List <Date> lstDate = new ArrayList<Date>();
        LocalDate start = new LocalDate(dtStart);
        LocalDate end = new LocalDate(dtEnd);
        Period period = Period.weeks(13);
        Period current = Period.ZERO;
        while (true) {
            LocalDate candidate = start.plus(current);
            if (candidate.isEqual(end) || candidate.isAfter(end)) {
                lstDate.add(dtEnd); 
                return lstDate;
            }
            else {
                lstDate.add(candidate.toDate());                
            }
            current = current.plus(period);
        }
    }
     
}

Friday, May 18, 2012

Internews - New Report: Closing the Loop — Responding to Information Needs in Haiti

Information matters, especially for individuals affected by severe crises like the 2010 earthquake in Haiti. But critically, new research shows that listening to audiences may be just as important.

Read the rest of the story here.

JQuery Offset Error

I was working on a drop-down menu that was fixed at the top of the page. It worked in Firefox, but not IE or Chrome. By using the developer tools in Chrome I discovered that there was an error on getting the offset position. The error message was "Cannot read property 'tagName' of null" and was being caused by the jQuery dimensions plugin. This plugin was used by the previous menu and wasn't needed any more so I removed it and the drop-down menus worked!

Friday, May 11, 2012

Using SQL to make a SharePoint Contact List

I needed to make a list of contact information for all of our offices using the contact information in Active Directory. All of the "regular" solutions were not applicable because the offices were contained in the same Organizational Unit as some other contacts, requiring the offices be filtered out from the other contacts. The solution was to use the SQL server that is used to host the databases for the SharePoint site to query AD and return the filtered list.

The first step is to create the SQL Linked server. I used SQL Management Studio to do this. Under "Server Objects, right click on "Linked Servers" and the click "New Linked Server".

Here are the settings you need to make. The "Data Source" is the name of your AD server.

On the "Security" page, enter the security settings:


Create the view:

CREATE VIEW [dbo].[vwWxyzOffices]
AS
SELECT sn[Country], homephone[Business Phone], l[City], streetAddress[Street Address], postalCode[Postal Code],
mail[Email], facsimileTelephoneNumber[Fax], mobile[Mobile Phone], info[Notes], wWWHomePage[Website]
FROM OPENQUERY(ADSI,
'SELECT givenName, sn, homephone, l, streetAddress, postalCode, facsimileTelephoneNumber,
mail, mobile, info, wWWHomePage
FROM ''LDAP://OU=Contacts,DC=Wxyz,DC=local''
WHERE objectClass = ''contact''  and givenName = ''Wxyz''')
GO

Finally, add the view into SharePoint as an external data source and use it in your SharePoint list!

Sunday, May 6, 2012

Tables Not Rendering Correctly in IE9

In the application that I'm working on I discovered that large tables were not rendering correctly in Internet Explorer 9. The same pages displayed correctly in IE8, Firefox, and Google Chrome. My first thought was that there was a problem in my page layout that only affected IE9. I looked over the HTML but couldn't find anything wrong. What I did notice was a large amount of white space. I wondered if that could cause the problem so I added the following to the top of the JSP page to strip out the extra white space.

<%@ page trimDirectiveWhitespaces="true" %>

Problem solved!

Wednesday, May 2, 2012

JNDI - Read Active Directory User Information

Today I needed to read in some user information from Active Directory so that I could create entries for each user and the uers group meberships in a SQL table.

Here is the code I used for testing:

package org.inewsnet.ldap;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.ResourceBundle;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class LdapJndi{
    @SuppressWarnings("rawtypes")
    Hashtable env;
    DirContext ctx;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public boolean  connect(){
        boolean bRes = true;
        ResourceBundle rsBun = ResourceBundle.getBundle("LDAP");
        env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://" + rsBun.getString("server") + ":" + 
           rsBun.getString("port") + rsBun.getString("root"));
        env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
        env.put(Context.SECURITY_PRINCIPAL, "cn=" + rsBun.getString("principal")); 
        env.put(Context.SECURITY_CREDENTIALS, rsBun.getString("credentials")); 
        try {
            ctx = new InitialDirContext(env);
        } catch (NamingException e) {
            e.printStackTrace();
            bRes = false;
        }
        return bRes;
    }

    public static String getCN(String cnName) {
        if (cnName != null && cnName.toUpperCase().startsWith("CN=")) {
            cnName = cnName.substring(3);
        }
        int position = cnName.indexOf(',');
        if (position == -1) {
            return cnName;
        } else {
            return cnName.substring(0, position);
        }
    }

    public static String getUserName(String upn) {
        int position = upn.indexOf('@');
        return upn.substring(0, position);
    }

    @SuppressWarnings("rawtypes")
    public boolean testNetworkRead() {
        boolean bRes = false;
        String firstName;
        String lastName;
        String userName;
        ResourceBundle rsBun = ResourceBundle.getBundle("LDAP");
        String bsaeOU = "ou=" + rsBun.getString("baseOU");
        SearchControls sc = new SearchControls();
        String[] attributeFilter = {"memberOf", "userPrincipalName", "sn", "givenName",  "cn", "mail" };
        sc.setReturningAttributes(attributeFilter);
        sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
        String filter = "(&(sn=*)(l=*))";

        try {
            NamingEnumeration results = ctx.search(bsaeOU, filter, sc);
            Integer iCx = 0;
            while (results.hasMore()) {
                SearchResult sr = (SearchResult) results.next();
                Attributes attrs = sr.getAttributes();
                iCx = iCx + 1;
                System.out.print(iCx + ")");
                Attribute attr = attrs.get("sn");
                lastName = attr.get().toString();
                System.out.print("ln= " + lastName);
                attr = attrs.get("givenName");
                if (attr != null) {
                    firstName = attr.get().toString();
                    System.out.print(" fn= " + firstName);
                }
                System.out.print("-");
                Attribute aupn = attrs.get("userPrincipalName");    
                userName = getUserName(aupn.get().toString());
                Attribute mattr = attrs.get("memberOf");
                System.out.println(" un= " + userName + ": ");        
                if(mattr != null) {
                    //loop through the memberof attribute to get each group
                    for ( Enumeration e1 = mattr.getAll() ; e1.hasMoreElements() ; ) {
                        System.out.println(getCN(e1.nextElement().toString()));
                    }
                }
            }//end while
            bRes = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            ctx.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }            
        return bRes;
    }
}

All you need to do is provide your own connection settings in the connect method. I'm getting mine from a properties file.

This is my test method calling the methods in the class above:

public String testLdapNetworkRead() throws Exception {
    LdapJndi myCon = new LdapJndi();
    try {
        if(myCon.connect()) myCon.testNetworkRead();
    } catch (Exception e) {
        this.errorMsg = e.getMessage();
        return ERROR;
    }
    successMsg = "Test Connect OK";
    return SUCCESS;
}   

Monday, April 30, 2012

A Simple Colorbox CSS File

After searching around on the Internet for a modal dialog box I settled on ColorBox because out of all of the modal dialog boxes out there it has the most of the the capabilities that I was looking for. The only thing that I did not like about it was the title bar and close button at the bottom. Unfortunately there isn't a setting for ColorBox to not show this section but I did find a way to eliminate it by changing the style sheet.The following CSS will do this for you. Just copy it and use it as your "colorbox.css" file. To simplify things I just used a plain solid box (mborder.png) for the border. All you have to do is supply your own image file.


The CSS:

#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:1111; overflow:hidden;}
#cboxOverlay{position:fixed; width:100%; height:100%;}
#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
#cboxContent{position:relative;}
#cboxLoadedContent{overflow:auto;}
#cboxTitle{margin:0;}
#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%;}
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
.cboxPhoto{float:left; margin:auto; border:0; display:block;}
.cboxIframe{width:100%; height:100%; display:block; border:0;}

#cboxOverlay{background:#222;}
#colorbox{}
#cboxTopLeft{width:8px; height:8px; background:url(images/mborder.png) no-repeat 0 0;}
#cboxTopCenter{height:8px; background:url(images/mborder.png) repeat-x top left;}
#cboxTopRight{width:8px; height:8px; background:url(images/mborder.png) no-repeat 0 0;}
#cboxBottomLeft{width:8px; height:8px; background:url(images/mborder.png) no-repeat 0 0;}
#cboxBottomCenter{height:8px; background-color:black; background:url(images/mborder.png) repeat-x bottom left;}
#cboxBottomRight{width:8px; height:8px; background:url(images/mborder.png) no-repeat 0 0;}
#cboxMiddleLeft{width:8px; background:url(images/mborder.png) repeat-y 0 0;}
#cboxMiddleRight{width:8px; background:url(images/mborder.png) repeat-y 0 0;}
#cboxContent{background:#fff; overflow:visible;} 
#cboxError{padding:50px; border:1px solid #ccc;}
#cboxLoadedContent{margin-bottom:5px;}
#cboxLoadingOverlay{background:url(images/loading_background.png) no-repeat center center;}
#cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
#cboxTitle{position:absolute; bottom:-25px; left:0; text-align:center; width:100%; font-weight:bold; color:#7C7C7C;}
#cboxCurrent{position:absolute; bottom:-25px; left:58px; font-weight:bold; color:#7C7C7C;}

Using this CSS in my application gave me a modal dialog box like this:

Saturday, April 28, 2012

Internews - A Multimedia Center in Afghanistan Helps People with Disabilities Access Technology

“Before coming to this center, I had little information about the Internet. Now I know how to use it to improve my life and profession. Now it is easy for me to solve my own professional problems and I can connect to the world very easily,” says Mohitullah Mujahid.

Mohitullah, an economics student from Nangarhar University who was born without hands and some of his toes, comes regularly to the Anaar Multimedia Center in Jalalabad to use the computers for his studies.

Read more here.

Saturday, April 21, 2012

Internews - Rapid Growth of Afghanistan’s ICT Sector Paves the Way for New Media and a Stronger Economy

Just ten years ago Afghanistan had a barely functional post-war infrastructure, with no independent media and literally no telecom services. Afghans had to travel to the neighboring countries to make a phone call. Today the story is very different, as outlined in a new independent study conducted by Javid Hamdard, of Internews, under the USAID-funded Afghanistan Media Development & Empowerment Project (AMDEP).

Read the complete report here.

MyBatis - Simple Mapper for Look-up Tables

In the database web application that I am working on there are over 30 look-up tables that are used for pick lists. I simplified reading in the data that I need for my application by using a generic mapper aclled "KeyValueDescriptionMapper". It uses the generic example class, BaseExample, that I describe here. By setting up the SQL statements in the mapper, KeyValueDescriptionMapper, so that the database field and the database table name can be specified by properties in the BaseExample class I am able to just use this one mapper to get me the list of key/value pairs I need for my pick lists!

The "KeyValueDescriptionMapper" mapper:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="KeyValueDescriptionMapper" >
    <!--
      author: Richard Golebiowski
      Generic mapper used to return key/value information
    -->
  <resultMap id="ExtKeyValueMap" type="com.utilSpace.util.ExtKeyValuePair" >
    <result column="ID" property="intKey" jdbcType="INTEGER" />
    <result column="Value" property="value" jdbcType="VARCHAR" />
    <result column="DescValue" property="descValue" jdbcType="VARCHAR" />    
  </resultMap>
  
  <sql id="Example_Where_Clause" >
    <where >
      <foreach collection="oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  
  <sql id="Update_By_Example_Where_Clause" >
    <where >
      <foreach collection="example.oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  
  <sql id="Base_Column_List" >
    ID, Value, DescValue
  </sql>
  
  <select id="selectByExample" resultMap="ExtKeyValueMap" parameterType="com.interbase.model.BaseExample" >
    select
    <if test="distinct" >
      distinct
    </if>
    <include refid="Base_Column_List" />
    from ${table}
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>
  </select>
  
  <select id="selectByPrimaryKey" resultMap="ExtKeyValueMap" parameterType="com.interbase.model.BaseExample" >
    select 
    <include refid="Base_Column_List" />
    from ${table}
    where ID = #{ID,jdbcType=INTEGER}
  </select>
  
  <delete id="deleteByPrimaryKey" parameterType="com.interbase.model.BaseExample" >
    delete from ${table}
    where ID = #{ID,jdbcType=INTEGER}
  </delete>
  
  <delete id="deleteByExample" parameterType="com.interbase.model.BaseExample" >
    delete from ${table}
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </delete>
  
  <insert id="insert" parameterType="com.utilSpace.util.ExtKeyValuePair" >
    insert into ${table} (ID, Value, DescValue
      )
    values (#{ID,jdbcType=INTEGER}, #{value,jdbcType=VARCHAR}, #{descValue,jdbcType=VARCHAR}
      )
  </insert>
  
  <insert id="insertSelective" parameterType="com.utilSpace.util.ExtKeyValuePair" >
    insert into ${table}
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="ID != null" >
        ID,
      </if>
      <if test="value != null" >
        Value,
      </if>
      <if test="descValue != null" >
        DescValue,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="ID != null" >
        #{ID,jdbcType=INTEGER},
      </if>
      <if test="value != null" >
        #{value,jdbcType=VARCHAR},
      </if>
      <if test="descValue != null" >
        #{descValue,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>

  <update id="updateByPrimaryKeySelective" parameterType="com.utilSpace.util.ExtKeyValuePair" >
    update ${table}
    <set >
      <if test="value != null" >
        Value = #{value,jdbcType=VARCHAR},
      </if>
      <if test="descValue != null" >
        DescValue = #{descValue,jdbcType=VARCHAR},
      </if>
    </set>
    where ID = #{ID,jdbcType=INTEGER}
  </update>
  
  <update id="updateByPrimaryKey" parameterType="com.utilSpace.util.ExtKeyValuePair" >
    update ${table}
    set Value = #{value,jdbcType=VARCHAR},
      DescValue = #{descValue,jdbcType=VARCHAR}
    where ID = #{ID,jdbcType=INTEGER}
  </update>

<!-- 
 Select records from the database table specified by the string parameter
-->      
  <select id="selectAllKeyValue" resultMap="ExtKeyValueMap" parameterType="java.lang.String">
    select ID, Value from ${value}
  </select>

<!-- 
 Select records from the database table specified by the string parameter
-->    
  <select id="loadDescSelectList" resultMap="ExtKeyValueMap" parameterType="java.lang.String">
    select  ID, Value,  DescValue from ${value} order by DescValue
  </select>
  
<!-- 
 Select records from the database table specified by the string parameter and the  "Value" field returned as "DescValue"
-->     
  <select id="loadValueDescSelectList" resultMap="ExtKeyValueMap" parameterType="java.lang.String">
    select  ID, Value as DescValue from ${value} order by DescValue
  </select>

<!-- 
 Select records from the database with the field specified by the "field" property returned as "Value"
-->    
  <select id="loadFieldAsValue" resultMap="ExtKeyValueMap" parameterType="com.interbase.model.BaseExample">
    select  ID, ${field} as Value from ${table}
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>        
  </select>
  
<!-- 
 Select records from the database with the field specified by the "field" property returned as "DescValue"
-->    
  <select id="loadFieldAsDescValue" resultMap="ExtKeyValueMap" parameterType="com.interbase.model.BaseExample">
    select  ID, ${field} as DescValue from ${table}
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>       
  </select>      
</mapper>

Usage Examples:
Use "selectAllKeyValue" to get a list from the "luMediaType" table:

GenericDataService lstServiceTest = new GenericDataService("KeyValueDescriptionMapper");
List <ExtKeyValuePair> tstList =  (List<ExtKeyValuePair>) lstServiceTest.selectAllKeyValue("luMediaType");


Using BaseExample to get a list from the "Funder" table with the "FunderShortName" database field as the value and sorted by "FunderShortName":

GenericDataService genService = new GenericDataService("KeyValueDescriptionMapper");
BaseExample baseExample = new BaseExample();
baseExample.setTable("Funder");
baseExample.setField("FunderShortName");
baseExample.setOrderByClause("FunderShortName");
List keyList = (List) genService.getFieldAsValue(baseExample);  


The "getFieldAsValue" method for the example above:

public  List getFieldAsValue(BaseExample baseExample){
    SqlSession session = this.sqlSessionFactoryINform.openSession();
    try {
        @SuppressWarnings("unchecked")
        List list = session.selectList(this.dataMapper + ".loadFieldAsValue", baseExample);
        return list;
    }catch(Exception e){
        System.out.println(e.getMessage());
        return null;
    } finally {
        session.close();
    }
}

Wednesday, April 18, 2012

MyBatis Generator - Generic Example Class

One of the things that I like about the mapper files created by MyBatis Generator is the ability to set up some basic query filter using the "Example" class that application creates. You can read more about them here. What I don't like about the "Example" classes is that they are specific to the class file that is created to map to the table. So if you have a large project like I do with around 25 main tables you would have 25 different "Example" classes. To get around this I created the following generic "Example" class. Use it in place of the "Example" classes created by the generator.

BaseExample class:

package com.interbase.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Basic database example class
 * @author Richard Golebiowski
 *
 */
public class BaseExample {
    protected List oredCriteria;    
    protected boolean distinct;
    protected String orderByClause;
    protected String table;//table name
    protected String field;//field name
    protected String queryName;//name of the query
    protected BaseCriteria baseCriteria = new BaseCriteria();
    
    public BaseExample() {
        this.oredCriteria = new ArrayList();
    }
    
    /**
     * Used to clear out current criteria
     */
    public void reset(){
        oredCriteria = new ArrayList();
        this.distinct = false;
        this.orderByClause = null;
        this.baseCriteria = new BaseCriteria();       
    }

    public void resetBase() {
        this.baseCriteria = new BaseCriteria();       
    }
    
    public void orCriteria() {
        oredCriteria.add(this.baseCriteria);
    }

    public void andCriterion(String condition, Object value) {
        baseCriteria.addCriterion(condition, value, condition);    
    }
    
    public void andCommonCriterion(String fieldName, String condition, Object value) {
        if(condition.equals("begins with")) {
            condition = "like";
            value = value + "%";
        }
        else if(condition.equals("contains")){
            condition = "like";
            value = "%" + value + "%";     
        }
        else if(condition.equals("ends with")){
            condition = "like";
            value = "%" + value;
        }
        else if(condition.equals("equals")){
             condition = "=";    
        } 
        condition = fieldName + " " + condition;
        baseCriteria.addCriterion(condition, value, condition);    
    }
    
    public void andCriterion(DataViewCriteria dataViewCriteria) {
        if(dataViewCriteria.getValue1() == null) {
            baseCriteria.addCriterion(dataViewCriteria.getFieldName() + " " + dataViewCriteria.getCondition());
        }
        else if(dataViewCriteria.getValue2() == null){
            baseCriteria.addCriterion(dataViewCriteria.getFieldName() + " " + dataViewCriteria.getCondition(), dataViewCriteria.getValue1(), dataViewCriteria.getFieldName());
        }
        else{
            baseCriteria.addCriterion(dataViewCriteria.getFieldName() + " " + dataViewCriteria.getCondition(), dataViewCriteria.getValue1(), dataViewCriteria.getValue2(), dataViewCriteria.getFieldName());        
        }
    }
    
    public void addCriterion(DataViewCriteria dataViewCriteria) {
        this.baseCriteria = new BaseCriteria();
        if(dataViewCriteria.getValue1() == null) {
            baseCriteria.addCriterion(dataViewCriteria.getFieldName() + " " + dataViewCriteria.getCondition());
            oredCriteria.add(baseCriteria);
        }
        else if(dataViewCriteria.getValue2() == null){
            baseCriteria.addCriterion(dataViewCriteria.getFieldName() + " " + dataViewCriteria.getCondition(), dataViewCriteria.getValue1(), dataViewCriteria.getFieldName());
            oredCriteria.add(baseCriteria);
        }
        else{
            baseCriteria.addCriterion(dataViewCriteria.getFieldName() + " " + dataViewCriteria.getCondition(), dataViewCriteria.getValue1(), dataViewCriteria.getValue2(), dataViewCriteria.getFieldName());
            oredCriteria.add(baseCriteria);
        }
    }

    public void addCriterion(String condition, Object value) {
        this.baseCriteria = new BaseCriteria();
        baseCriteria.addCriterion(condition, value, condition);
        oredCriteria.add(baseCriteria);
    }
    
    public void addCriterion(String condition) {
        if (condition == null) {
            throw new RuntimeException("Value for condition cannot be null");
        }
        this.baseCriteria = new BaseCriteria();
        baseCriteria.addCriterion(condition);
    }

    public void addCriterion(String condition, Object value, String property) {
        if (value == null) {
            throw new RuntimeException("Value for " + property + " cannot be null");
        }
        this.baseCriteria = new BaseCriteria();
        baseCriteria.addCriterion(condition, value, property);
    }

    public void addCriterion(String condition, Object value1, Object value2, String property) {
        if (value1 == null || value2 == null) {
            throw new RuntimeException("Between values for " + property + " cannot be null");
        }
        this.baseCriteria = new BaseCriteria();
        baseCriteria.addCriterion(condition, value1, value2,property);
    }

    public void addCriterionForJDBCDate(String condition, Date value, String property) {
        if (value == null) {
            throw new RuntimeException("Value for " + property + " cannot be null");
        }
        addCriterion(condition, new java.sql.Date(value.getTime()), property);
    }

    public void addCriterionForJDBCDate(String condition, List values, String property) {
        if (values == null || values.size() == 0) {
            throw new RuntimeException("Value list for " + property + " cannot be null or empty");
        }
        List dateList = new ArrayList();
        Iterator iter = values.iterator();
        while (iter.hasNext()) {
            dateList.add(new java.sql.Date(iter.next().getTime()));
        }
        addCriterion(condition, dateList, property);
    }

    public void addCriterionForJDBCDate(String condition, Date value1, Date value2, String property) {
        if (value1 == null || value2 == null) {
            throw new RuntimeException("Between values for " + property + " cannot be null");
        }
        addCriterion(condition, new java.sql.Date(value1.getTime()), new java.sql.Date(value2.getTime()), property);
    }    
    

    public List getOredCriteria() {
        return oredCriteria;
    }

    public void setOredCriteria(List oredCriteria) {
        this.oredCriteria = oredCriteria;
    }
    
    public void setDistinct(boolean distinct) {
        this.distinct = distinct;
    }
    
    public boolean isDistinct() {
        return distinct;
    }
    
    public void setOrderByClause(String orderByClause) {
        this.orderByClause = orderByClause;
    }

    public String getOrderByClause() {
        return orderByClause;
    }

    public String getTable() {
        return table;
    }

    public void setTable(String table) {
        this.table = table;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String getQueryName() {
        return queryName;
    }

    public void setQueryName(String queryName) {
        this.queryName = queryName;
    }

    public BaseCriteria getBaseCriteria() {
        return baseCriteria;
    }

    public void setBaseCriteria(BaseCriteria baseCriteria) {
        this.baseCriteria = baseCriteria;
    }    
}


BaseCriteria class:

package com.interbase.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/**
 * Basic criteria class
 * @author Richard Golebiowski
 *
 */
public class BaseCriteria {
 protected List criteria;
 
    public BaseCriteria() {
        this.criteria = new ArrayList();
    } 
    public boolean isValid() {
        return criteria.size() > 0;
    }

    public List getAllCriteria() {
        return criteria;
    }

    public List getCriteria() {
        return criteria;
    }

    public void addCriterion(String condition) {
        if (condition == null) {
            throw new RuntimeException("Value for condition cannot be null");
        }
        criteria.add(new Criterion(condition));
    }

    public void addCriterion(String condition, Object value, String property) {
        if (value == null) {
            throw new RuntimeException("Value for " + property + " cannot be null");
        }
        criteria.add(new Criterion(condition, value));
    }

    public void addCriterion(String condition, Object value1, Object value2, String property) {
        if (value1 == null || value2 == null) {
            throw new RuntimeException("Between values for " + property + " cannot be null");
        }
        criteria.add(new Criterion(condition, value1, value2));
    }

    public void addCriterionForJDBCDate(String condition, Date value, String property) {
        if (value == null) {
            throw new RuntimeException("Value for " + property + " cannot be null");
        }
        addCriterion(condition, new java.sql.Date(value.getTime()), property);
    }

    public void addCriterionForJDBCDate(String condition, List values, String property) {
        if (values == null || values.size() == 0) {
            throw new RuntimeException("Value list for " + property + " cannot be null or empty");
        }
        List dateList = new ArrayList();
        Iterator iter = values.iterator();
        while (iter.hasNext()) {
            dateList.add(new java.sql.Date(iter.next().getTime()));
        }
        addCriterion(condition, dateList, property);
    }

    public void addCriterionForJDBCDate(String condition, Date value1, Date value2, String property) {
        if (value1 == null || value2 == null) {
            throw new RuntimeException("Between values for " + property + " cannot be null");
        }
        addCriterion(condition, new java.sql.Date(value1.getTime()), new java.sql.Date(value2.getTime()), property);
    }    
}



Example usage:

GenericDataService genService = new GenericDataService("DataViewCriteriaMapper");
BaseExample baseExample = new BaseExample();
baseExample.addCriterion("DataViewID =", this.viewID);
//get the criteria for the view
this.lstDataViewCriteria = (List) genService.getListByExample(baseExample);

GenericDataService Class:

package com.dataSpace.service;

public class GenericDataService extends DataService {
 
 public GenericDataService(String dataMapper){
  this.dataMapper = dataMapper;
 }
 
 public GenericDataService() {

 }

 public void switchDataMapper(String dataMapper){
  this.dataMapper = dataMapper;
 }
 

}
DataService Class:

package com.dataSpace.service;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;

import com.interbase.mapper.MyBatisConnectionFactory_INform;
import com.interbase.model.BaseExample;
import  com.utilSpace.util.ExtKeyValuePair;
import  com.utilSpace.util.KeyValuePair;

public abstract class DataService {
 private static final Logger logger = Logger.getLogger(DataService.class);
 protected SqlSessionFactory sqlSessionFactoryINform = MyBatisConnectionFactory_INform.getSqlSessionFactory();
 protected String dataMapper;
 protected boolean errorFlag;
 protected String errorMsg;
 
 public List<Object> getAll(){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   List<Object> list = session.selectList(this.dataMapper + ".selectAll");
   return list;
  } finally {
   session.close();
  }    
 }
 
 public List<KeyValuePair> getByMethod(String method){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   List<KeyValuePair> list = session.selectList(this.dataMapper + "." + method);
   return list;
  } finally {
   session.close();
  }    
 }
 
 public List<ExtKeyValuePair> getExtByMethod(String method){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   List<ExtKeyValuePair> list = session.selectList(this.dataMapper + "." + method);
   return list;
  } finally {
   session.close();
  }    
 }
 
 public List<?> getListByExample(BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   List<Object> list = session.selectList(this.dataMapper + ".selectByExample", baseExample);
   return list;
  }catch(Exception e){
   System.out.println(e.getMessage());
   this.errorFlag = true;
   this.errorMsg = e.getMessage();
   return null;
  } finally {
   session.close();
  }    
 }
 
 public List<?> getListFromTableByExample(BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   List<Object> list = session.selectList(this.dataMapper + ".selectFromTableByExample", baseExample);
   return list;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;
  } finally {
   session.close();
  }    
 }
 
 public List<?> getListByMethodAndExample(String method, BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   List<Object> list = session.selectList(this.dataMapper + "." + method, baseExample);
   return list;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;
  } finally {
   session.close();
  }    
 }  
 
 public Object getRecordByMethodAndExample(String method, BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   Object obj = session.selectOne(this.dataMapper + "." + method, baseExample);
   return obj;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;
  } finally {
   session.close();
  }    
 }
 
 public Object getByMethodWithID(String method, Integer id){
  SqlSession session = sqlSessionFactoryINform.openSession();
  try {
   Object obj = session.selectOne(this.dataMapper + "." + method, id);
   return obj;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;
  } finally {
   session.close();
  }   
 }
  
 public Object getRecordByExample(BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   this.errorFlag = false;
   Object obj = session.selectOne(this.dataMapper + ".selectByExample", baseExample);
   return obj;
  }catch(Exception e){
   this.errorFlag = true;
   return null;
  } finally {
   session.close();
  }    
 } 
 
 public Object getRecordByQueryExample(BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   Object obj = session.selectOne(this.dataMapper + "." + baseExample.getQueryName(), baseExample);
   return obj;
  } finally {
   session.close();
  }    
 } 
 
 public Object getByID(Integer id){
  SqlSession session = sqlSessionFactoryINform.openSession();
  try {
   Object obj = session.selectOne(this.dataMapper + ".selectByPrimaryKey", id);
   return obj;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;
  } finally {
   session.close();
  }   
 }
 
 public void updateByID(Object obj){
  SqlSession session = sqlSessionFactoryINform.openSession();
  try {
   session.update(this.dataMapper + ".updateByPrimaryKey", obj);
   session.commit();
  }catch(Exception e){
   System.out.println(e.getMessage());
  } finally {
   session.close();
  } 
 }
 
 public Object insert(Object obj){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   session.insert(this.dataMapper + ".insert", obj);
   session.commit();
  } catch(Exception e){
   System.out.println(e.getMessage());
  }finally {
   session.close();
  } 
  return obj;  
 }
 
 public void deleteByID(Integer id){
  SqlSession session = sqlSessionFactoryINform.openSession();
  try {
   this.errorFlag = false;
   session.delete(this.dataMapper + ".deleteByPrimaryKey", id);
   session.commit();
  }catch(Exception e){
   this.errorFlag = true;
   logger.error(e.getMessage());
  } finally {
   session.close();
  } 
 } 
 
 public void deleteByExample(BaseExample baseExample){
  SqlSession session = sqlSessionFactoryINform.openSession();
  try {
   this.errorFlag = false;
   session.delete(this.dataMapper + ".deleteByExample", baseExample);
   session.commit();
  }catch(Exception e){
   this.errorFlag = true;
   logger.error(e.getMessage());
  } finally {
   session.close();
  } 
 } 
 
 public List<ExtKeyValuePair> selectAllKeyValue(String source){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   List<ExtKeyValuePair> list = session.selectList(this.dataMapper + ".selectAllKeyValue", source);
   return list;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;   
  } finally {
   session.close();
  }
 }
 
 public List<ExtKeyValuePair> getFRomTableByMethod(String source, String method){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")
   List<ExtKeyValuePair> list = session.selectList(this.dataMapper + "." + method, source);
   return list;
  } finally {
   session.close();
  }    
 }
 
 /**
  * Select records from the database with the field specified by the "field" property returned as "Value"
  * @param baseExample
  * @return
  */
 public ExtKeyValuePair loadFieldAsValue(BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   Object kvp = session.selectOne(this.dataMapper + ".loadFieldAsValue", baseExample);
   return (ExtKeyValuePair) kvp;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;   
  } finally {
   session.close();
  }
 }
 
 /**
  * Select records from the database with the field specified by the "field" property returned as "Value"
  * @param baseExample
  * @return
  */
 public  List<ExtKeyValuePair> getFieldAsValue(BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")   
   List<ExtKeyValuePair> list = session.selectList(this.dataMapper + ".loadFieldAsValue", baseExample);
   return list;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;   
  } finally {
   session.close();
  }
 }
 /**
  * Select records from the database with the field specified by the "field" property returned as "Value"
  * @param baseExample
  * @return
  */
 public  List<ExtKeyValuePair> getFieldAsDescValue(BaseExample baseExample){
  SqlSession session = this.sqlSessionFactoryINform.openSession();
  try {
   @SuppressWarnings("unchecked")   
   List<ExtKeyValuePair> list = session.selectList(this.dataMapper + ".loadFieldAsDescValue", baseExample);
   return list;
  }catch(Exception e){
   System.out.println(e.getMessage());
   return null;   
  } finally {
   session.close();
  }
 }

 public boolean isErrorFlag() {
  return errorFlag;
 }

 public void setErrorFlag(boolean errorFlag) {
  this.errorFlag = errorFlag;
 }

 public String getErrorMsg() {
  return errorMsg;
 }

 public void setErrorMsg(String errorMsg) {
  this.errorMsg = errorMsg;
 }
 
}

Wednesday, April 11, 2012

TSQL - Date and Formated Count

On the project I'm working on I need to set a field to the to a two digit date and sequential count number when a new record is added. The format is YY-### where YY is the year and ### is the count. So the first record for 2012 would be 12-001, the next is 12-002, and so on.

This is how I did it.

DECLARE @ret int
DECLARE @count int
DECLARE @val varchar(6)
--get the two digit year
SET @ret = (YEAR(GETDATE()) % 100)
--count the number of records where the controlnum begins with the year and add 1
select @count = count(*)+1 from parosc where controlnum like CONVERT(varchar, @ret) + '%'
--combine
set @val = CONVERT(varchar(2), @ret) + '-' + right('00' + CONVERT(varchar, @count), 3)

I just made it into a User Defined Function and set the default value for the ControlNum field to the function.

Afghan National Radio Network Launches as Independent NGO | Internews

Nine years after its establishment, Salam Watandar ("Hello Countrymen") Radio was officially inaugurated April 8 as an independent, non-governmental Afghan organization.

More at Afghan National Radio Network Launches as Independent NGO | Internews

Monday, April 9, 2012

MyBatis - MyBatis Generator

I have been using MyBatis Generator for about a year now on two different projects. It's a great help in building the structures you need in an application for doing database CRUD operations. Read More

Sunday, April 8, 2012

Java, XML - Read/Write a List of Objects

One of the things that I have been doing in my applications is using XML files to store lists. As illustrated by these two short methods, the XStream library makes this very easy to do .

Write a list of class FieldDescriptor to a file:

private static void saveFieldDefinitions(String fieldDescriptorName, LinkedList<FieldDescriptor> list) throws IOException {
    XStream xs = new XStream();
    xs.alias("FieldDescriptor", FieldDescriptor.class); 
    //Write
    try {
        FileOutputStream fs = new FileOutputStream(fieldDefinitionsFilePath + "\\" + fieldDescriptorName + ".xml");
        xs.toXML(list, fs);
        fs.close();
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    }
}


Reada list of class FieldDescriptor from a file:

protected void loadFieldDefinitions(String fieldDescriptorName) {
    XStream xs = new XStream(new DomDriver());
    xs.alias("FieldDescriptor", FieldDescriptor.class);        
    //Read
    try {
        FileInputStream  fs = new FileInputStream(fieldDefinitionsFilePath + "\\" + fieldDescriptorName + ".xml");
        lstFieldDescriptor = (List<FieldDescriptor>) xs.fromXML(fs);
        fs.close();
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    } catch(Exception e2) {
        e2.printStackTrace();
    }
}

Sunday, April 1, 2012

jQuery, AJAX, Struts - Add a Select Box Option

Here is a quick little example on how to add a new option to a select box and make the new value the selected value.

On my JSP page I have two select boxes that can have new values added. When a new value for an Award or Project is add, the new value will be added as an option to the select box and made the selected value.


A modal dialog box is used to enter a new Award or Project. In this image, you can see a section of the dialog box for adding a new Award. In the dark area you will see a section of the original record edit screen.


Here is the section from the JSP page for the select box. Since the forms are generated dynamically, the id of my select box can have any value so I need to return that value to the server so that it can be used later on as the AJAX target. In the code snippet below you see this value being returned as the "target" parameter.

<s:select name="tableRecord.tblRecord.%{fieldName}" id="disp%{fieldName}" list="selectListMap(fkeyName)" headerKey="" headerValue="Please Select"/>
<s:if test="fkeyPrimaryTableName != null">
 <s:url var="urlFkey" namespace="%{namespace}" action="GotoAddForeignKeyRecord" escapeAmp="false">
  <s:param name="target" >disp${fieldName}</s:param>
  <s:param name="fkeyName" value="fkeyName"/>
  <s:param name="fkeyTableName" value="fkeyPrimaryTableName"/>
 </s:url>
 <s:a href="%{urlFkey}" cssClass='ajax'>
  Add New <s:property value="fkeyPrimaryTableNameLabel"/>
 </s:a>
 <script type="text/javascript">
 $(".ajax").colorbox({width:'800', close:'close'});
 </script>
</s:if>


I use XML files to define the fields for the database tables. Here is the section from the XML file that describes the awardID.

<FieldDescriptor>
    <fieldName>awardID</fieldName>
    <fieldLabel>Award</fieldLabel>
    <fieldType>1</fieldType>
    <fieldSize>0</fieldSize>
    <editable>true</editable>
    <listable>true</listable>
    <required>true</required>    
    <fkeyName>lstAwards</fkeyName>
    <fkeyPrimaryTableName>Award</fkeyPrimaryTableName>
    <fkeyPrimaryTableNameLabel>Award</fkeyPrimaryTableNameLabel>
    <fkeyListEditable>true</fkeyListEditable>
</FieldDescriptor>   


Don't get hung up on this XML structure or the information it contains. The import part follows, getting the new value into the select box.

Here is my GotoAddForeignKeyRecord action method. Notice that the target for my AJAX action is being saved as ajaxTarget.

public String gotoAddForeignKeyRecord(){
 String fkeyName = request.getParameter("fkeyName");
 //save the target for the AJAX action
 this.ajaxTarget = request.getParameter("target");
 this.baseTableDescriptor = TableDescriptorFactory.getFieldDescriptor(table); 
 for(KeyDescriptor kD: this.baseTableDescriptor.getLstKeyDescriptor()){
  if(kD.getName().equals(fkeyName)){
   String tMapper = kD.getMapper();
   if(kD.getTableMapper() != null) {
    tMapper = kD.getTableMapper();
   }
                        //luTableField is used for the display value in the select box on the JSP page
   this.luTableField = kD.getLuTableField();
   //set the Struts namespace for the table we are targeting
   this.redirectNamespace = "/" + tMapper.replace("Mapper", "").toLowerCase();
   //set the page that we will be redirecting to
   this.redirectPage = "AddForeignKeyRecord";
   this.recordID = null;
   return SUCCESS;
  }
 }
 return ERROR;
}


The section from the record add JSP page with the jQuery code for populating the select box. The values that I need for the key and value I get from the "${tablename}ID" and "disp${luTableField}" on the JSP page.

<s:url id="urlCancelRecordAdd" namespace="%{namespace}" action="NoOpp"/>
<sj:submit  value="Cancel" formIds="saveRecordFK" id="cancelFKRecordEdit" href="%{urlCancelRecordEdit}" onclick="parent.$.colorbox.close();return false;" button="true" style="font-size: .7em;"/>
</td>
</tr>
<script type="text/javascript">
//submit the list
$('#cancelFKRecordAdd').click(function() {
 //if we have an ID then we have a record so update the sellect box
 if($('#${tablename}ID').val() != ''){
        //make the markup for the option for the select box
 var option = '<option value=' + $('#${tablename}ID').val() + '>' + $('#disp${luTableField}').val() + '</option>';
        //add the option to the select box
 $('#${ajaxTarget}').append(option);
        //set the added option as the selected value
 $("#${ajaxTarget}").val($('#${tablename}ID').val());
 }
});
</script>

Saturday, March 31, 2012

Call for Applications for 2012 Media Policy Fellowships | Internews

Ten fully-funded fellowships to participate in the 14th annual Annenberg-Oxford Media Policy Summer Institute are available for qualified applicants from the developing world.

For details see: Call for Applications for 2012 Media Policy Fellowships | Internews

jQuery, AJAX, JSON - Mofify Select Box Options


In my Struts action I populate a list, lstDataView, and then use Flexjson to serialize:

public String appTableChange() throws Exception {
 if(request.getParameter("this.appTableID") != null){
  this.appTableID = Integer.parseInt(request.getParameter("this.appTableID"));
 }
 if(this.appTableID != null){
  SessionService.removeAttributeFromSession(request, "LstViewRecords");
  //load the list of views
  loadTableViews();
  //serialize the list
  String jsonResult = new flexjson.JSONSerializer().serialize(lstDataView);
  response.setContentType("text/javascript");
  response.getWriter().write(jsonResult);
 }
 return null;
}


Each entry in the list has two fields, ID and title. ID will be used for the key and title will be used for the value when I create the options. Here is the snippet of script from my JSP page. Using getJSON, I call the Struts action listed above. Then I iterate through the returned result to create the string of options and change the options in the select box.

$.getJSON("../AppTableChange.action", {appTableID: $(this).val(), ajax: 'true'}, function(j){
var options = '<option value=-1>Please Select</option>';
 for (var i = 0; i < j.length; i++) {
  options += '<option value="' + j[i].ID + '">' + j[i].title + '</option>';
 }
 $("select#viewID").html(options);
})

Tuesday, March 27, 2012

PowerShell - Get Exchange Distribution Group Information

Today I was asked to create a list of our Exchange distribution groups showing the name of the group, list owner, and the notes field. Here is the script I used. The Get-Group PowerShell command is used to get the notes field. Output is sent to a csv file.

# Initialize array
$totalObj = @()

# Retrieve all DGs
$temp = Get-DistributionGroup -ResultSize Unlimited | select-Object name, managedby, @{n="Notes";e={(Get-Group $_).Notes}} |

# Loop through all distribution groups
ForEach-Object {

  # Create instance of object of type .NET
  $obj = New-Object System.Object

  # Add the name of the DG to the object
  #if ($i -eq 0) {
   $obj | Add-Member -MemberType NoteProperty -Value $_.name -Name 'Distribution Group' -Force
  #}

  # Add list owner of the DG to the object
  $obj | Add-Member -MemberType NoteProperty -Value $_.managedby -Name 'DG Manager' -Force 

  # Add notes of the DG to the object
  $obj | Add-Member -MemberType NoteProperty -Value $_.Notes -Name 'Description' -Force 
  
  # Add the object to the array
  $totalObj += $obj

}

# Pipe output to .csv file
$totalObj | Export-Csv c:\exchangescripts\ListMembers3-2012man.csv