Friday, January 30, 2009

UnsupportedEncodingException: Cp850

I am using JCIFS so that I can use Windows Authentication for my Java web application running under Apache. The authentication prompts me for a username and password as expected when I use FireFox. However, when I access the exact same page using Internet Explorer I get a 500 error, and then I check the apache log and see the following message:

Jan 30, 2009 8:06:52 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.io.UnsupportedEncodingException: Cp850
 at sun.io.Converters.getConverterClass(Unknown Source)
 at sun.io.Converters.newConverter(Unknown Source)
 at sun.io.ByteToCharConverter.getConverter(Unknown Source)
 at java.lang.StringCoding.decode(Unknown Source)
 at java.lang.String.<init>(Unknown Source)
 at java.lang.String.<init>(Unknown Source)
 at jcifs.ntlmssp.Type1Message.parse(Type1Message.java:236)
 at jcifs.ntlmssp.Type1Message.<init>(Type1Message.java:86)
 at jcifs.http.NtlmSsp.authenticate(NtlmSsp.java:88)
 at jcifs.http.NtlmHttpFilter.negotiate(NtlmHttpFilter.java:160)
 at jcifs.http.NtlmHttpFilter.doFilter(NtlmHttpFilter.java:114)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
 at java.lang.Thread.run(Unknown Source)


After some digging and reviewing the docs (
https://thea.openintegra.com/project/sauron/browser/vendor/jcifs/current/docs/overview.html?rev=149&format=txt)  for JCIFS, I see that there is a jcifs.encoding property that can be set. The default is Cp850. It appears that Cp850 refers to an encoding. I set the jcifs.encoding to ASCII then Internet Explorer works without prompting for a password and renders the page as expected.

You can set the jcifs.encoding property as described in the JCIFS docs (see above link). I put mine in the Initialization Parameters for the Servlet Filter called NtlmHttpFilter.

I read that you can use Cp1252 instead of ASCII and that should work also, but I have not verified. I also read that Cp850 is in the jre-lib/charsets.jar and that the Cp1252 is in the rt.jar. I tried adding charsets.jar to my class path and it didn't seem to help. 

I read the other way to fix the issue is to install the Enterprise version or at least a version that has the internationalized JVM. I didn't want to change the version of java running on my app server due to change management, etc, but I expect that would have worked. I did not try this solution, but I believe it would work because I didn't have the issue when running locally or on another server. I expect may also have to due with the character set that the target server is set up with. I don't really know where to find that to verify though. Any info on this is appreciated.

Thursday, January 15, 2009

How to use HyperLinks GridView with AutoGenerateColumns="True"

Let's assume for some reason, you want to keep AutoGenerateColumns="true" for your GridView, but you want to show a hyperlink in one or more of your columns as a hyperlink. This should also work if AutoGenerateColumns="false" and want to still use BoundField columns. Another scenario might be you want to have embeded html. In either case, GridView is trying to help you by not allowing html (and javascript) be displayed by default. If you are specifying your own columns you can use the TemplateField, etc, but what do you do you do when you don't have that kind of control until Runtime?

Below is a simple solution. It simply converts the escaped HTML back to raw HTML for the browser to render.

protected void gvResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
  // check if each cell in the row has a hyperlink in it,
  // if it does then unescape the html so that it will render as rawhtml

  if (e.Row.RowType == DataControlRowType.DataRow)
  {
   for (int i = 0; i < e.Row.Cells.Count; i++)
   {
    if (e.Row.Cells[i].Text.ToUpper().Contains("&LT;A"))
    {
     e.Row.Cells[i].Text = Server.HtmlDecode(e.Row.Cells[i].Text);
    }

   }
  }

}

There are a few of things to note here.

This method needs to be hooked up to the RowDataBound event of your GridView.

Once you do that this method will fire for each row of data. The looping is really just looking for cells that hyperlinks in them. We have to search for the escaped version of html instead of the raw html. The ToUpper() method is called since we don't know if the link will be like <A or <a.

If you know what column the hyperlink is in the code could be simplified to something like the following code. In this example, we assume the hyperlink or embeded html is in the second column. 

protected void gvResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
 e.Row.Cells[1].Text = Server.HtmlDecode(e.Row.Cells[1].Text);
}

Wednesday, January 14, 2009

SharePoint Web Template types

SharePoint has different types of templates that you can choose when you create a web site. The different types are

  • Blog
  • Central Admin
  • Invalid (not really a type)
  • Meeting
  • Team Collaboration Site
  • Wiki

I wanted to find out how users were using SharePoint. I know SharePoint has a MS SQL Server backend where it stores all its data. The data is stored in the Content database. In Windows SharePoint Services 2.0 (WSS2) and SharePoint Portal Server 2003 (SPS) the content database typically ends in _SITE. In Windows SharePoint Services 3.0 (WSS3) and Microsoft SharePoint Server 2007 (MOSS) the database is typically called something like _Content. For example WSS_Content.

There is no web template table that enumerates all the types of web templates. However, web sites which are stored in the Webs table in the content database do store what kind of web template was used to create the site. The WebTemplate column of the Webs table is where this value is stored

Now you can do a SQL CASE statement in your select statement to give meaningful type descriptions instead of number. For example:

select
case WebTemplate
WHEN 9 THEN 'Blog'
WHEN 3 THEN 'Central Admin'
WHEN -1 THEN 'Invalid'
WHEN 2 THEN 'Meeting'
WHEN 1 THEN 'Team Collaboration Site'
WHEN 4 THEN 'Wiki'
END
from webs

That is not very useful query though. I recommend the following query that enumerates each of the web template types and reports how many sites are of each type.

select
case WebTemplateCode
WHEN 9 THEN 'Blog'
WHEN 3 THEN 'Central Admin'
WHEN -1 THEN 'Invalid'
WHEN 2 THEN 'Meeting'
WHEN 1 THEN 'Team Collaboration Site'
WHEN 4 THEN 'Wiki'
END as WebTemplate2,
count(w.webtemplate) as NumOfSites
from Webs w
right outer join (select 9 as WebTemplateCode union select 3 union select -1 union select 2 union select 1 union select 4) webTemplates
on (w.WebTemplate = webTemplates.WebTemplateCode)
group by WebTemplateCode
order by 1


Output from this query would look something like the following:

Blog 3
Central Admin 0
Invalid 0 Meeting 20
Team Collaboration Site 16
Wiki 4

Friday, January 9, 2009

What are valid values for tp_servertemplate and what do they map to?

SharePoint has a MS SQL Server backend where it stores all its data. The data is stored in the Content database. In Windows SharePoint Services 2.0 (WSS2) and SharePoint Portal Server 2003 (SPS) the content database typically ends in _SITE. In Windows SharePoint Services 3.0 (WSS3) and Microsoft SharePoint Server 2007 (MOSS) the database is typically called something like _Content. For example WSS_Content.

All lists use the LISTS table. The sp_servertemplate column can be used to find all lists of a particular type, etc. The list varies a little bit between versions of SharePoint. For instance there are new values for blog and wiki in MOSS and WSS3, but they do not exist in WSS2 and SPS. As far as I know the newer version of SharePoint simply add more values, they don't change existing ones.

The question quickly becomes, "What are valid values for tp_servertemplate and what do they map to?" Below you will find such a list of possible values and what they map to in a user friendly and human readable format.

This text is essentially the text from the Microsoft Windows SharePoint Services 3.0 SDK or the actual docs

Optional Integer. Provides a unique identifier for the list definition. This identifier must be unique within the feature, but need not be unique across all feature definitions or site definitions. Windows SharePoint Services 3.0 includes the following list types by default.

  • 100 Generic list

  • 101 Document library

  • 102 Survey

  • 103 Links list

  • 104 Announcements list

  • 105 Contacts list

  • 106 Events list

  • 107 Tasks list

  • 108 Discussion board

  • 109 Picture library

  • 110 Data sources

  • 111 Site template gallery

  • 112 User Information list

  • 113 Web Part gallery

  • 114 List template gallery

  • 115 XML Form library

  • 116 Master pages gallery

  • 117 No-Code Workflows

  • 118 Custom Workflow Process

  • 119 Wiki Page library

  • 120 Custom grid for a list

  • 130 Data Connection library

  • 140 Workflow History

  • 150 Gantt Tasks list

  • 200 Meeting Series list

  • 201 Meeting Agenda list

  • 202 Meeting Attendees list

  • 204 Meeting Decisions list

  • 207 Meeting Objectives list

  • 210 Meeting text box

  • 211 Meeting Things To Bring list

  • 212 Meeting Workspace Pages list

  • 301 Blog Posts list

  • 302 Blog Comments list

  • 303 Blog Categories list

  • 1100 Issue tracking

  • 1200 Administrator tasks list

For custom list templates this attribute should be set to a number above 10000 to ensure that it does not conflict with any present or future Microsoft supplied list types.

Now you can do a SQL CASE statement in your select statement to give meaningful type descriptions instead of number. For example:

select case tp_servertemplate when 100 then 'Generic list' when 101 then 'Document library' when 102 then 'Survey' when 103 then 'Links list' when 104 then 'Announcements list' when 105 then 'Contacts list' when 106 then 'Events list' when 107 then 'Tasks list' when 108 then 'Discussion board' when 109 then 'Picture library' when 110 then 'Data sources' when 111 then 'Site template gallery' when 112 then 'User Information list' when 113 then 'Web Part gallery' when 114 then 'List template gallery' when 115 then 'XML Form library' when 116 then 'Master pages gallery' when 117 then 'No-Code Workflows' when 118 then 'Custom Workflow Process' when 119 then 'Wiki Page library' when 120 then 'Custom grid for a list' when 130 then 'Data Connection library' when 140 then 'Workflow History' when 150 then 'Gantt Tasks list' when 200 then 'Meeting Series list' when 201 then 'Meeting Agenda list' when 202 then 'Meeting Attendees list' when 204 then 'Meeting Decisions list' when 207 then 'Meeting Objectives list' when 210 then 'Meeting text box' when 211 then 'Meeting Things To Bring list' when 212 then 'Meeting Workspace Pages list' when 301 then 'Blog Posts list' when 302 then 'Blog Comments list' when 303 then 'Blog Categories list' when 1100 then 'Issue tracking' when 1200 then 'Administrator tasks list' else 'Other' end 'ListType' from lists

Tuesday, January 6, 2009

What is the Group Policy?

What is a Group Policy Group Policy for Active Directory is used to control settings on many computers using once central location for all the settings. The settings are pushed out to the many computers at some interval or an event such as rebooting a computer. The changes (in most cases) are stored applied to the many computers by changing values in the registries of the many computers. This makes it possible to temporarily change group policies settings until the next application of the Group Policy settings. How do I see what Group Policies are being applied to my computer? You can open a command prompt and use the gpresult command. It is very simple to use and takes a couple of minutes to run. To run it just type gpresult at the command prompt and wait a couple minutes. Soon you will see some very useful information including what location your user account and your computer are in the Active Directory. Where in the heck is the Group Policy Editor? Well, it is hidden from you, just like the Registry Editor (regedit.exe) since it can mess up your computer if you don't know what you are doing. To open the Group Policy Editor all you have to do is go to the Start menu | Run... and then type gpedit.msc and click the OK button. You can also use the Group Policy Snap-in for the Management Console. Check out this article on how to do so. http://support.microsoft.com/kb/307882. Are there any other tools I should know about? I think a freely available snap-in for the Management Console from Microsoft called Group Policy Management Console with Service Pack 1. It can be downloaded from here. You add it very much the same as you do the Group Policy Snap-in described above. When you add it, look for Group Policy Management. How do I force my computer to get the latest Group Policy? Open a command prompt and type GPUPDATE /force

SharePoint Incoming E-mail Overview

Overview: You can integrate incoming e-mail capability into your sites. This new feature enables teams to aggregate e-mail messages within lists and libraries without the extra step of opening the site and uploading the content that was sent in e-mail. This is possible because most list and library types can be assigned a unique e-mail address. Site members can add the e-mail addresses of these lists in the To or Cc box of their e-mail client application when they send e-mail, or they can send e-mail to a distribution list that contains the e-mail addresses of these lists as well as the e-mail addresses of other site members. You can enable and configure e-mail support for the following types of lists and libraries in your sites: document libraries, picture libraries, form libraries, announcements lists, calendar lists, blogs, and discussion boards. Anyone with permissions to create a list can choose an e-mail address for the list when creating the list in an e-mail-enabled site. Note that you cannot add content to lists in Meeting Workspace sites by sending e-mail. For more information, please see here Technical Impact:
  • E-mail addresses will be able to be created by End Users
  • A new OU will need to be created. Call it SharePoint if you like.
  • Active Directory users will be able to be created by End Users. Though only in the SharePoint OU.
  • No use of a system admin should be needed once this is setup
  • A new MX record (Mail record) will need to be added to DNS
  • A SMTP Send Connector will need to be added to MS Exchange to route e-mails
  • New e-mail accounts for each "list". It will be automatically managed by SharePoint
Technical Requirements:
  • Functional Active Directory Account:
  • Create a new OU (Organizational Unit) in the Active Directory. For example, SharePoint
  • Delegate control of the newly created OU to the Functional account. Permissions should be Read, Write, Create All Child Object.
  • Add MX record to DNS server that points to our SharePoint server. For example, sharepoint.mycompany.com. This is required so that we can resolve the e-mail domain name to the SharePoint server once an e-mail is received by the company mail server.
  • SMTP Relay (A SMTP Relay can accept incoming and outgoing SMTP messages and forward them to their appropriate location. Basically an SMTP router.) This MUST be installed on the SharePoint server.
  • Configured SMTP connector within MS Exchange e-mail server that knows where to send e-mails we designate for SharePoint.

Cannot open this item. You cannot use SharePoint. Your system administrator has turned off the feature.

So you are using Windows SharePoint Services 3.0 (WSS) or Microsoft Office SharePoint Server 2007 (MOSS) and you get the following message:

Cannot open this item. You cannot use SharePoint. Your system administrator has turned off the feature.

Before I get to how to fix it, here are some of the ways you may encounter this message:

  • Any Task list | Actions toolbar item | Connect to Outlook
  • Receive an alert (from task, list, calendar, file, etc) in Outlook and try to open it.

What does this message mean, you ask? First, let me say that it doesn't necessary mean that your administrator has turned off the feature. For example, if you are trying to open an alert / notification sent from SharePoint notifying you that a list, task, file, etc has changed and you get this message it could be a bug with Exchange. Here is the link that describes the issue.

http://support.microsoft.com/default.aspx/kb/930807/en-us

On the other hand, it could very well be exactly what the message says. To tell if this functionality truly been disabled by your administrator as the message indicates, the easiest thing is to check the registry.

To check the registry, do the following:

  1. Start menu | Run... | regedit.exe
  2. Navigate to HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\12.0\Outlook\Options\WSS\Disable
  3. If the value for Disabled is 1 then the feature is indeed disabled by your administrator. If the value is 0 then it is not disabled and I would consider it to be a bug. If you don't have 12.0 in the path above then you likely don't have Outlook 2007 and are using another version of Outlook. In that case check out the following blog

    http://blogs.technet.com/josebda/archive/2007/01/27/enabling-and-disabling-sharepoint-integration-in-outlook-2007.aspx.

    Though from what I can tell the path for Outlook 2007 is incorrect. You can always try what I specified above and the one that is noted in that blog.

You can directly edit the registry and this will work for a while. Please note, you will likely need to restart Outlook 2007 for the change to take affect. The problem is that if you are in a larger organization or one that uses Group Policies to manage such things your changes will be overwritten the next time the Group Policies are applied to your computer. You may need to contact your adminstrator to determine why they disabled this functionality in the first place and ask if they can change the policy. Good luck ;)