Search This Blog

Wednesday, December 28, 2011

Improved IntelliJ keymap

At my current client the whole team recently switched from an Eclipse based IDE to IntelliJ. Although some of us have used IntelliJ for a long time, most had not. Switching from Eclipse to IntelliJ can be hard. It took me about three to four weeks before I was more productive with IntelliJ. Now I do not want to go back anymore.

To make the transition more smooth I am looking into several ways to accomplish this. One of the things I made is a new keymap reference for IntelliJ. The default keymap reference contains a whole list of shortcuts but I find them sometimes hard to find. The new, improved, keymap should make the most used IntelliJ features really easy to find. The most used features are based upon my own experience and the IntelliJ productivity guide of my colleagues. The productivity guide shows which features of IntelliJ are used most often.

To create the improved keymap reference I basically did the following:

  1. Stripped about half of the features from the default keymap reference. The features present on the new keymap reference are the most used features.
  2. Made a clearer distinction between the different types of functionality the features belong to.
  3. In each feature group I made a distinction between individual features which belong together.
  4. Used a larger font and more contrast to make things stand out more.
The Windows keymap reference can be found here: IntelliJ Keymap Windows
The OSX keymap reference can be found here: IntelliJ Keymap OSX

Hope you like it.

If you have any suggestions for the keymap reference please let me know.

Tuesday, August 2, 2011

WebSphere Portal 6.x Locale Resolution

When developing applications for WebSphere Portal there will be some point in time that the application should support I18N. For every language an application supports a resource bundle is provided. If a given language is not supported the application falls back to its default resource bundle. To format currencies and dates the JSTL formatting tags can be used. Based on the locale selection process of WebSphere Portal, the translation of dates and currencies in the correct locale may not what be exactly what you expect/want. This article provides a portal wide solution to handle locales in a consistent and transparent way.

Language selection process
WebSphere Portal server 6.x uses the following language selection process taken from the portal documentation:

  1. The language encoded in the URL takes highest priority. The portal does not encode a locale into the URL by default.
  2. If the user has logged in, the portal displays in the preferred language selected and stored in the user repository by the user.
  3. If no preferred user language can be found, the portal looks for the language defined in the user's browser. If the portal supports that language, it displays the content in that language. If the browser has more than one language defined, the portal uses the first language in the list to display the content.
  4. If no browser language can be found, for example if the browser used does not send a language, the portal resorts to its own default language.
  5. If the user has a portlet that does not support the language that was determined by the previous steps, that portlet is shown in its own default language.

By looking at step 3, the portal should accept the browser language if it supports this language. The same is true for the portlet itself. Unfortunately, it is not clear how the portal determines if a given language is supported or not. The documentation is not clear about this either.

By executing extensive tests (removing languages with XML access and removing the resource bundles of those specific language from portal) with different locales sent from the browser, the portal always took the language from the browser if the user did not have a specific language set in its user profile. This is not an issue with the resource bundles since the application falls back to its default resource bundle if the language is not supported. The JSTL tags however did not use the proper language which resulted in dates and currencies formatted in the locale of the browser. Since we wanted tight control of the language used, this behaviour was not an option for us. We wanted a Portal wide solution which did not impact application design/implementation. 

The portal documentation mentions something about a locale filter. Portal itself provides two implementations of this filter: ExtendedLocaleFilter and SortingLocaleFilter. It is also possible to implement a custom filter.

The code of the provided locale filters can be found in C:\IBM\WP61\PortalServer\base\wp.engine.impl\shared\app\wp.engine.impl.jar file.

Decompiling those filters you can see that the implementation reflects the above language selection process. The filters use the Puma API to determine the user’s locale. Also, by looking at this implementation you get a good idea of how to efficiently build a custom locale filter.

The following filter is an example filter which always fixes the locale to en_US regardless of the user profile or browser setting.



   1:  public class FixedLocaleFilter implements Filter {
   2:      public void init(final FilterConfig aFilterConfig) throws ServletException {
   3:      }
   4:   
   5:      public void doFilter(final ServletRequest aServletRequest, final ServletResponse aResponse, final FilterChain aFilterChain) throws IOException, ServletException {
   6:          if (aServletRequest instanceof HttpServletRequest) {
   7:              aFilterChain.doFilter(new FixedLocaleHttpServletRequest((HttpServletRequest) aServletRequest), aResponse);
   8:          } else {
   9:              aFilterChain.doFilter(aServletRequest, aResponse);
  10:          }
  11:      }
  12:   
  13:      public void destroy() {
  14:   
  15:      }
  16:  }
  17:   
  18:  public class FixedLocaleHttpServletRequest extends HttpServletRequestWrapper {
  19:      private static final Locale EN = new Locale("en", "US");
  20:      private static final Vector<Locale> LOCALES = new Vector<Locale>() {{
  21:          add(EN);
  22:      }};
  23:      private static final Vector<String> ACCEPT_LANGUAGE_EN_US = new Vector<String>() {{
  24:          add("en-US");
  25:      }};
  26:   
  27:      public FixedLocaleHttpServletRequest (HttpServletRequest request) {
  28:          super(request);
  29:      }
  30:   
  31:      @Override
  32:      public Locale getLocale() {
  33:          return EN;
  34:      }
  35:   
  36:      @Override
  37:      public Enumeration getLocales() {
  38:          return LOCALES.elements();
  39:      }
  40:   
  41:      public String getHeader(String header) {
  42:          if (isAcceptLanguageHeader(header))
  43:              return "en-US";
  44:          else
  45:              return super.getHeader(header);
  46:      }
  47:   
  48:      public Enumeration getHeaders(String s) {
  49:          if (isAcceptLanguageHeader(s))
  50:              return ACCEPT_LANGUAGE_EN_US.elements();
  51:          else
  52:              return super.getHeaders(s);
  53:      }
  54:   
  55:      private boolean isAcceptLanguageHeader(String s) {
  56:          return s.intern() == "Accept-Language" || s.equalsIgnoreCase("Accept-Language");
  57:      }
  58:  }

The above FixedLocaleFilter just wraps the incoming request in a FixedLocaleHttpServletRequest. The next step is to configure this filter in the web.xml of the Portal application web.xml. The web.xml can be found in wp_profile_root/config/cells/node-name/applications/wps.ear/deployments/wps/wps.war/WEB-INF.

See the following example configuration:



   1:  <filter>
   2:          <filter-name>Locale Filter</filter-name>
   3:          <!--<filter-class>com.ibm.wps.engine.ExtendedLocaleFilter</filter-class>-->
   4:          <filter-class>FixedLocaleFilter</filter-class>
   5:      </filter>

Please note that the above sample code is just an example unless you want a fixed locale of en_US for the whole profile where the portal is deployed. A practical scenario would be a custom filter which uses the following language selection process:
  1. If the user has set a locale in its profile use that one.
  2. If the user has not set a locale use the browsers locale if the locale is supported.
  3. If the browser locale is not supported use the default locale of the portal.
The above steps can easily be implemented using a custom locale filter. You can also use init parameters to make the filter configurable.

Conclusion
Letting all applications in a WebSphere portal behave the same regarding locale resolution can be hard/impossible if you do not want to implement custom locale handling code within the applications itself. By using a custom locale filter in WebSphere portal, the locale resolution code is kept in one place. This makes locale resolution transparent and clear to all applications running in the portal. 


Monday, June 6, 2011

search engine meta information

Microsoft, Google and Yahoo, the companies behind the three major search engines Bing, Yahoo and Google, have launched a new initiative to add meta data to an HTML document. This meta data is used by the aforementioned search engines to improve the displaying of search results.

Consider the following example:
<html>
    <div class="product">
        <!-- product information comes here. -->
    <div>
</html>

The reader of this HTML fragment immediately sees that this is something about product information. A computer program, like a search engine instead, cannot determine that this information is actually about products.

To help search engines, and potentially other software, understand the meta information behind the information, http://www.schema.org describes a shared vocabulary which can be used to add meta data to HTML tags.

Consider the revisited example:
<html>
    <div class="product" itemscope itemtype="http://schema.org/Product">
        <!-- product information comes here. -->
    <div>
</html>

By adding the itemscope attribute, you are telling the information between the div element is about a particular item. The itemtype attribute narrows this item further as a Product. This way, search engine can potentially add this information to an online product catalog making your products easier to find. Other types are available as wel, for example:
  • Movie
  • Event
  • Organisation
I implemented this meta tags for a new webshop I am building. These attributes are part of the HTML5 standard and therefore cannot be used by an XHTML1.1 strict syntax without passing the W3C validation. To use these attributes, just declare your document as HTML5. You can then use the W3C validator to fix any validation errors which may arise. I think this is worth the exercise.


One step further to the semantic web.

Friday, January 21, 2011

Deploying Hippo on JBoss 4.2.3GA and PostgresQL 8.3

For a client of us we developed a public website with the Hippo CMS. Hippo CMS is a Java based Content Management System based on the Content Repository API. Hippo runs standard on Apache Tomcat and Mysql. We wanted to deploy Hippo on JBoss 4.2.3GA with Postgres 8.3. Below is a step-by-step guide to deploy Hippo 7, the cms.war artifact, on Jboss with Postgres 8.3.


1. Create a PostgresQL database
Before you can deploy the cms.war file a PostgresQL database must be created. Hippo demands a database encoding of Latin1. If your PostgresQL database server is installed with a different encoding, excluding C or POSIX, you may not be able to create a Latin1 encoded database. If this is the case you can do one of the following:
    1. Re-install the database server with a Latin1, C or POSIX locale. By using the C or POSIX locale you can create a database with any encoding you like, including Latin1.
    2. Create a database with an encoding the current database server supports, for example UTF-8, and change the encoding of the database with the following SQL statement: ALTER DATABASE dbX SET client_encoding TO latin1; Make sure you restart the database server.
2. Add the postgress JDBC-driver to the /server/default/lib


3. Create a datasource
Create a datasource in Jboss by creating a postgres-ds.xml in the /server/default/deploy directory with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
    <local-tx-datasource>
        <jndi-name>jdbc/repositoryDS</jndi-name>
        <connection-url>jdbc:postgresql://localhost:5432/hippo</connection-url>
        <driver-class>org.postgresql.Driver</driver-class>
        <user-name>postgres</user-name>
        <password>postgres</password>-->
        <blocking-timeout-millis>5000</blocking-timeout-millis> 
          <idle-timeout-minutes>5</idle-timeout-minutes> 
     <prepared-statement-cache-size>50</prepared-statement-cache-size>
       </local-tx-datasource>
</datasources>

4. Add a resource-ref to the cms.war web.xml
Add the following resource-ref to the web.xml of the cms.war file:
 <resource-ref>
        <res-ref-name>jdbc/repositoryDS</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

You can add this element just before the closing </web-app> element.

5. Add a jboss-web.xml file to root of the WEB-INF directory of the cms.war
The jboss-web.xml defines the mapping between the datasource and the resource-ref. This file should have the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<resource-ref>
  <res-ref-name>jdbc/repositoryDS</res-ref-name> 
  <jndi-name>java:/jdbc/repositoryDS</jndi-name> 
</resource-ref>
</jboss-web>

6. Modify the location of the repository.xml in the web.xml of the cms.war
We have to create a custom repository.xml file which configures Hippo for using PostgresQL. The location of the repository path should be modified so that it can find out repository.xml file. Change the location of the repository.xml file in de web.xml file to the following:
<servlet>
        <servlet-name>Repository</servlet-name>
        <servlet-class>org.hippoecm.repository.RepositoryServlet</servlet-class>
        <init-param>
            <param-name>repository-config</param-name>
            <param-value>repository.xml</param-value>
            <description>The location of the repository configuration file.
                Unless the location
                starts with file://, the location is retrieved from within the application
                package as
                resource.</description>
        </init-param>
        <load-on-startup>4</load-on-startup>
    </servlet>

7. Add the customized repository.xml file to the cms.war file
The following repository.xml file should be added to the the cms.war file in the directory: WEB-INF/classes/org/hippoecm/repository. The bundle-cache is enabled in the following repository.xml which greatly improves the performance of the Hippo cms system. The cache size is set to 256MB but can be altered when needed.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.5//EN"
      "http://jackrabbit.apache.org/dtd/repository-1.5.dtd">
<Repository>

    <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
        <param name="url" value="java:comp/env/jdbc/repositoryDS" />
        <param name="driver" value="javax.naming.InitialContext" />
        <param name="schemaObjectPrefix" value="repository_" />
        <param name="schema" value="postgresql" />
    </FileSystem>

    <Security appName="Jackrabbit">
        <SecurityManager class="org.hippoecm.repository.security.SecurityManager" />
        <AccessManager class="org.hippoecm.repository.security.HippoAccessManager" />
        <LoginModule class="org.hippoecm.repository.security.HippoLoginModule" />
    </Security>

    <Workspaces rootPath="${rep.home}/workspaces"
        defaultWorkspace="default" />
    <Workspace name="${wsp.name}">
        <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
            <param name="url" value="java:comp/env/jdbc/repositoryDS" />
            <param name="driver" value="javax.naming.InitialContext" />
            <param name="schemaObjectPrefix" value="${wsp.name}_" />
            <param name="schema" value="postgresql" />
        </FileSystem>

        <PersistenceManager
            class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager">
            <param name="driver" value="javax.naming.InitialContext" />
            <param name="url" value="java:comp/env/jdbc/repositoryDS" />
            <param name="schemaObjectPrefix" value="${wsp.name}_" />
            <param name="externalBLOBs" value="true" />
            <param name="consistencyCheck" value="true" />
            <param name="consistencyFix" value="true" />
            <param name="bundleCacheSize" value="256"/>
        </PersistenceManager>

        <SearchIndex
            class="org.hippoecm.repository.FacetedNavigationEngineThirdImpl">
            <param name="indexingConfiguration" value="indexing_configuration.xml" />
            <param name="indexingConfigurationClass"
                value="org.hippoecm.repository.query.lucene.ServicingIndexingConfigurationImpl" />
            <param name="path" value="${wsp.home}/index" />
            <param name="useCompoundFile" value="true" />
            <param name="minMergeDocs" value="1000" />
            <param name="volatileIdleTime" value="10" />
            <param name="maxMergeDocs" value="1000000000" />
            <param name="mergeFactor" value="5" />
            <param name="maxFieldLength" value="10000" />
            <param name="bufferSize" value="1000" />
            <param name="cacheSize" value="1000" />
            <param name="forceConsistencyCheck" value="true" />
            <param name="enableConsistencyCheck" value="true" />
            <param name="autoRepair" value="true" />
            <param name="analyzer"
                value="org.apache.lucene.analysis.standard.StandardAnalyzer" />
            <param name="queryClass" value="org.apache.jackrabbit.core.query.QueryImpl" />
            <param name="respectDocumentOrder" value="false" />
            <param name="resultFetchSize" value="2147483647" />
            <param name="extractorPoolSize" value="0" />
            <param name="extractorTimeout" value="100" />
            <param name="extractorBackLogSize" value="100" />
            <param name="textFilterClasses"
                value="org.apache.jackrabbit.extractor.PlainTextExtractor,org.apache.jackrabbit.extractor.MsWordTextExtractor,org.apache.jackrabbit.extractor.MsExcelTextExtractor,org.apache.jackrabbit.extractor.MsPowerPointTextExtractor,org.apache.jackrabbit.extractor.PdfTextExtractor,org.apache.jackrabbit.extractor.OpenOfficeTextExtractor,org.apache.jackrabbit.extractor.RTFTextExtractor,org.apache.jackrabbit.extractor.HTMLTextExtractor,org.apache.jackrabbit.extractor.XMLTextExtractor" />
        </SearchIndex>
    </Workspace>

    <Versioning rootPath="${rep.home}/version">
        <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
            <param name="url" value="java:comp/env/jdbc/repositoryDS" />
            <param name="driver" value="javax.naming.InitialContext" />
            <param name="schemaObjectPrefix" value="version_" />
            <param name="schema" value="postgresql" />
        </FileSystem>

        <PersistenceManager
            class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager">
            <param name="driver" value="javax.naming.InitialContext" />
            <param name="url" value="java:comp/env/jdbc/repositoryDS" />
            <param name="schemaObjectPrefix" value="version_" />
            <param name="externalBLOBs" value="true" />
            <param name="consistencyCheck" value="true" />
            <param name="consistencyFix" value="true" />
            <param name="bundleCacheSize" value="256"/>
        </PersistenceManager>
    </Versioning>

    <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
        <param name="path" value="${rep.home}/repository/index" />
        <param name="forceConsistencyCheck" value="true" />
        <param name="enableConsistencyCheck" value="true" />
    </SearchIndex>

    <DataStore class="org.apache.jackrabbit.core.data.db.DbDataStore">
        <param name="url" value="java:comp/env/jdbc/repositoryDS" />
        <param name="driver" value="javax.naming.InitialContext" />
        <param name="databaseType" value="postgresql" />
        <param name="minRecordLength" value="1024" />
        <param name="maxConnections" value="5" />
        <param name="copyWhenReading" value="true" />
    </DataStore>
</Repository>

8. Optionally: change the heap and permsize settings of JBoss.
I use the following memory settings for my configuration. Modify this in the run.bat startup script: set JAVA_OPTS=%JAVA_OPTS% -Xms256m -Xmx768m -XX:MaxPermSize=256m
    Thats it!

    Wednesday, January 12, 2011

    Second Swiz workshop

    On February the 16th I will be giving the second Swiz workshop for the Dutch Flex User Group. The workshop has been upgraded to Swiz 1.0 instead of 0.6. In this workshop I will show you how to apply the MVC pattern to Flex applications using the Swiz framework. More information about Swiz can be found here.

    Registration is still open since there are still some seats available. You can register here.

    See you there!

    Tuesday, January 4, 2011

    20 Useful development tools

    In this post I will take a look at 20, mostly free, useful tools which I use during my day-to-day software development. I am not talking about IDE's (I use various ones) here but small useful tools to increase developer productivity. The tools are listed in no particular order.
    1. IETester
      IITester can be used to test websites in various versions of Internet Explorer. A lot of website still require IE6 which can be difficult to test under Windows Vista or Windows 7. IETester provides a viable alternative which let you test your website in IE5.5, 6, 7 and 8. IETester can be found here.
    2. PuTTY
      PuTTY is an open source terminal emulator which can act as a client for SSH, Telnet and other protocols. Useful tool for the remote management of computers. PuTTY can be found here.
    3. Notepad++
      Notepad++ is a free source and text file editor which I use daily for text file editing. I do not use Notpad++ as a source code editor but it does support syntax highlighting for various languages. I find this useful as I sometimes use Notepad++ to look at source files. Notepad++ supports various plugins and does also have a column editing mode. To enable column editing mode just hold the "Alt" key and select the text with your left mouse button. Notepad++ can be found here.
    4. ArgoSoft Mail Server
      ArgoSoft mail server is a mail server which you can use on your localhost to sent and receive mails using POP3 en SMTP. This is a very useful tool when testing e-mail functionality in any application. ArgoSoft mail server Freeware edition can be found here.
    5. GEDIS Studio
      GEDIS studio is a test data generation tool. They also have a free community edition which you can use to generate test data. The community edition also comes with text files which contains useful testdata which you can use to generate your own test- data/files. GEDIS studio can be found here.
    6. FileZilla client
      FileZilla client is a free FTP client which I use a lot to transfer files to other machines using FTP. The FTP client is available for multiple platforms and can be found here.
    7. MySQL Workbench
      For some projects I use MySQL. When working with MySQL I usually use the MySQL workbench for SQL development and server administration. The tool can also be used for data modeling. MySQL workbench can be found here.
    8. JRebel
      When doing Java development I find the time it takes to reload changes in Java source files to publish back to the server frustratingly slow. JRebel enables the changes you make in Java source files to immediately be reflected in the runtime environment for example Tomcat, JBoss or WebSphere. Although JRebel is not free the money is really worth it. JRebel can be found here.
    9. VMWare player
      I mainly develop on Windows 7. Sometimes I need to check something in another operating system, for example Ubuntu. VMWare player is a useful tool to run other operating systems in an easy way. I also use VMWare player when I give workshops. Instead of installing the prerequisites on every client machine, I distribute a VMWare image which participants use during the workshop. This saves me a lot of setup time and frustration. VMWare player can be found here.
    10. Paint.NET/Gimp
      Although graphic design is not my primary expertise I sometimes have the need to edit images for my web projects. I use Paint.NET and Gimp for this depending on what I need to do. Paint.NET can be found here and Gimp can be found here.
    11. SQLite Administrator
      SQLite Administrator is a powerful tool if you easily want to create, design or administrate SQLite database files. I use SQLite Administrator for example when I use SQLite with Adobe Air. SQLite Administrator can be found here.
    12. Selenium IDE/iMacro
      When testing certain functionality during web application development you often must perform a sequence of steps before you can test the actual functionality. Selenium and iMacro let you record these steps and automate this process. This saves you a lot of time when testing the same functionality several times. SeleniumIDE can be found here and iMacro can be found here.
    13. Firebug
      Firebug is useful tool when doing web application development. This Firefox plugin enables you to inspect the HTML and modify it in real time and analyze network traffic. Firebug also has a JavaScript debugger. Firebug can be found in the Firefox add-on window.
    14. Chrome
      Chome also has a lot of useful tools when doing web application development. The tools in Chrome I use most are the element inspector, JavaScript debugger and network analysis tool.
    15. YSlow
      YSlow is a Firebug extension which analyzes a web application based on client side performance indicators developed by Yahoo. YSlow makes suggestions in how to optimize the client side performance of your web application. YSlow can be found in the Firefox add-on window.
    16. PageSpeed
      PageSpeed is a similar tool as YSlow but PageSpeed is developed by Google. I use both YSlow and PageSpeed. PageSpeed can be found here.
    17. SoapUI
      SoapUI is a Java based tool for testing web services. SoapUI has a basic version for free which can be found here.
    18. Tamper data
      Tamper data is Firefox plugin to view and modify HTTP/HTTPS header and modify POST parameters. I use this tool for inspecting traffic sent from the browser to the server and for testing the security of web applications. Tamper data can be found here.
    19. REST Client
      REST Client is a Firefox plugin to easily test REST services and can be found here.
    20. Fiddler
      Fiddler is a web debugging proxy which can be used inspect the traffic sent from your browser over the Internet. I use this tool a lot in analyzing the traffic between the web application under development and the backend. It also supports HTTPS. Fiddler can be found here.
     This list is not exhaustive so I would like to know which tools you use?