Spell checking with suggestions with Hibernate Search 4 and Lucene 3.6

In latest releases of Hibernate Search 4 and Lucene 3.6 there was some changes in SpellChecker API’s.
Here is example of the new API that allows to use spell checking with suggested words:

public String[] getSuggestions(String txt){
	String[] suggestions =  new String[]{};

	FullTextSession fullTextSession = Search.getFullTextSession(sf.getCurrentSession());
	SearchFactory searchFactory = fullTextSession.getSearchFactory();
	IndexReader reader = searchFactory.getIndexReaderAccessor().open(MyEntity.class);
	try {
		FSDirectory spellCheckerDir = FSDirectory.open(new File("D:\\lucene\\spellchecker\\com.site.model.MyEntity"));
		SpellChecker spellChecker = new SpellChecker(spellCheckerDir);
		Dictionary dictionary = new LuceneDictionary(reader, "description");
		IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_35, searchFactory.getAnalyzer("myAnalyzer"));
		spellChecker.indexDictionary(dictionary, config, true);
		suggestions = spellChecker.suggestSimilar(txt, 10);
	} catch (Exception e) {
		e.printStackTrace();
	}
	finally{
		searchFactory.getIndexReaderAccessor().close(reader);
	}
	return suggestions;
}

sf.getCurrentSession() gets standard Hibernate session. If you use EntityManager, there exists a method to obtain FullTextSession.
The example creates new index directory dedicated to spell checking. It adds terms from MyEntity’s description field to the index. spellChecker.indexDictionary adds the terms to the index, and optionally merges it with existing index.

Portlets with Wicket 1.5.x in Liferay portal

After Wicket dropped support for portlets and moving it to wicketstuff the settings in XMLs are changed:

portlet.xml should look like

<portlet>
	<description>wickettest4</description>
	<portlet-name>wickettest4</portlet-name>
	<display-name>wickettest4</display-name>
	<portlet-class>org.apache.wicket.portlet.WicketPortlet</portlet-class>
	<init-param>
		<name>wicketFilterPath</name>
		<value>/bla</value>
	</init-param>
	<supports>
		<mime-type>text/html</mime-type>
		<portlet-mode>VIEW</portlet-mode>
	</supports>
	<portlet-info>
		<title>wickettest4</title>
		<keywords>wickettest4</keywords>
	</portlet-info>
</portlet>

Note new portlet-class. Also, mime-type have to be text/html.

web.xml also changed, notice filter class:

<filter>
	<filter-name>wicket.wicket</filter-name>
	<filter-class>org.apache.wicket.portlet.PortletFilter</filter-class>
	<init-param>
		<param-name>applicationClassName</param-name>
		<param-value>org.wicket.WicketApplication</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>wicket.wicket</filter-name>
	<url-pattern>/bla/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>INCLUDE</dispatcher>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>

And of course Maven dependencies also changed:

<dependency>
	<groupId>org.apache.wicket</groupId>
	<artifactId>wicket-core</artifactId>
	<version>${wicket.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.portals.bridges</groupId>
	<artifactId>portals-bridges-common</artifactId>
	<version>2.0</version>
</dependency>
<dependency>
	<groupId>org.wicketstuff</groupId>
	<artifactId>wicketstuff-portlet</artifactId>
	<version>${wicket.version}</version>
</dependency>

 

Create datasource programmatically on JBoss 7

In order to create new datasource programmatically on JBoss 7 without restart (on the fly) from Java you can use CLI Java API. You have to include jboss-as-controller-client to your project dependencies:

<dependency>
	<groupId>org.jboss.as</groupId>
	<artifactId>jboss-as-controller-client</artifactId>
	<version>7.0.2.Final</version>
</dependency>

The following example creates new datasource:

public void createDatasource() throws Exception{
	ModelNode request = new ModelNode();
	request.get(ClientConstants.OP).set(ClientConstants.ADD);
	request.get(ClientConstants.OP_ADDR).add("subsystem",
			"datasources");
	request.get(ClientConstants.OP_ADDR).add("data-source",
			"java:jboss/datasources/NewDatasource");

	request.get("jndi-name").set("java:jboss/datasources/NewDatasource");
	request.get("connection-url").set("jdbc:as400://1.2.3.4/SCHEME");
	request.get("driver-class").set("com.ibm.as400.access.AS400JDBCDriver");
	request.get("driver-name").set("jt400.jar");
	request.get("user-name").set("username");
	request.get("password").set("password");
	request.get("pool-name").set("pool_NewDatasource");

	ModelControllerClient client = ModelControllerClient.Factory.create(
			InetAddress.getByName("127.0.0.1"), 9999);
	client.execute(new OperationBuilder(request).build());
}

If you want to check if the datasource already exists, consider following snippet:

public boolean checkIfDatasourceExists() throws Exception {
	ModelNode request = new ModelNode();
	request.get(ClientConstants.OP).set("read-resource");
	request.get("recursive").set(false);
	request.get(ClientConstants.OP_ADDR).add("subsystem", "datasources");

	ModelControllerClient client = ModelControllerClient.Factory.create(
			InetAddress.getByName("127.0.0.1"), 9999);
	ModelNode responce = client.execute(new OperationBuilder(request).build());

	ModelNode datasources = responce.get(ClientConstants.RESULT).get("data-source");

	if (datasources.isDefined()) {
		for (ModelNode dataSource : datasources.asList()) {
			String dataSourceName = dataSource.asProperty().getName();
			if (dataSourceName.equals("java:jboss/datasources/NewDatasource")) {
				return true;
			}
		}
	}
	return false;
}

The examples have the same effect as trying to add datasource from Jboss Administration console.

Cleaning eclipse with -clean argument

For those of you who work a lot with Eclipse,
you probably run into all sorts of strange errors in Eclipse that
not really related to your code, and then you get the feeling that Eclipse has gone mad.

One way to solve these problems and clean the Eclipse is using -clean argument.
all you need to do is to edit the eclipse.ini file located in your <Eclipse install directory> and add it as the first argument on the first line.
After you upload the eclipse you can delete it until the next time you will need it.

Forcing JBoss 7 to apply changes to JSP’s immediately

JBoss AS 7 by default do not reflect any changes to JSP files in WAR deployment. So, during application development you have to redeploy WAR or restart JBoss. In order to change this behaviour it is necessary to change section of urn:jboss:domain:web:1.0 in standalone.xml so it looks like:

<subsystem xmlns="urn:jboss:domain:web:1.0" default-virtual-server="default-host">
    <configuration>
        <jsp-configuration development="true"/>
    </configuration>
    ...
</subsystem>

And now JBoss behaves as you expect it in development mode: all changes to JSP files are loaded automatically as soon as you change the JSP file.