If set parameter target to _blank of the following lefary tag:

<liferay-ui:icon image=""  label=""  target="_blank"  message=""  url=""/>

It just shows “Opens New Window” beside the link text but not open link page in new tab.

If you look source of taglib/ui/icon/page.jsp you will see

<aui:a href="<%= url %>" id="<%= id %>" lang="<%= lang %>" target="<%= target %>">

<%= linkContent %>

</aui:a>

It creates link using aui:a tag here I found if I remove id parameter it woks fine. I mean if I make it like bellow:

<aui:a href="<%= url %>" lang="<%= lang %>" target="<%= target %>">

<%= linkContent %>

</aui:a>

It opens link page in new tab if target parameter set to _blank of liferay-ui:icon otherwise it opens on same window though target parameter is set to _blank.

We need to use regular expression frequently in text processing for search, parse, validation or XML document integrity. Java provide us a package called java.util.regex to make life easier for regular expression. Bellow I have summarized the things as I need to use Java Regex so frequently 🙂

Common matching symbols:

Regular Expression Description
. Matches any sign
^regex regex must match at the beginning of the line
regex$ Finds regex must match at the end of the line
[abc] Set definition, can match the letter a or b or c
[abc[vz]] Set definition, can match a or b or c followed by either v or z
[^abc] When a “^” appears as the first character inside [] when it negates the pattern. This can match any character except a or b or c
[a-d1-7] Ranges, letter between a and d and figures from 1 to 7, will not match d1
X|Z Finds X or Z
XZ Finds X directly followed by Z
$ Checks if a line end follows

Metacharacters:

Regular Expression Description
\d Any digit, short for [0-9]
\D A non-digit, short for [^0-9]
\s A whitespace character, short for [ \t\n\x0b\r\f]
\S A non-whitespace character, for short for [^\s]
\w A word character, short for [a-zA-Z_0-9]
\W A non-word character [^\w]
\S+ Several non-whitespace characters

Characters:

Characters Description
x The character x
\\ The backslash character
n The character with octal value 0n (0<=n<=7)
nn The character with octal value 0nn (0<=n<=7)
mnn The character with octal value 0mnn (0<=m<=3, 0<=n<=7)
\xhh The character with hexadecimal value 0xhh
\uhhhh The character with hexadecimal value 0xhhhh
\t The tab character ('\u0009')
\n The newline (line feed) character ('\u000A')
\r The carriage-return character ('\u000D')
\f The form-feed character ('\u000C')
\a The alert (bell) character ('\u0007')
\e The escape character ('\u001B')
\cx The control character corresponding to x

Quantifier:

Regular Expression Description Examples
* Occurs zero or more times, is short for {0,} X* – Finds no or several letter X, .* – any character sequence
+ Occurs one or more times, is short for {1,} X+ – Finds one or several letter X
? Occurs no or one times, ? is short for {0,1} X? -Finds no or exactly one letter X
{X} Occurs X number of times, {} describes the order of the preceding liberal \d{3} – Three digits, .{10} – any character sequence of length 10
{X,Y} .Occurs between X and Y times, \d{1,4}- \d must occur at least once and at a maximum of four
*? ? after a qualifier makes it a “reluctant quantifier”, it tries to find the smallest match.

A simple example for case insensitive URL matching using java Regex given bellow:

java.util.regex.Pattern p = Pattern.compile(“(\\s*|^)((ht|f)tp(s?)://)?([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?(\\s*|$)”,Pattern.CASE_INSENSITIVE);
for getting URL with port number we can apply the following pattern:
(\\s*|^)(((ht|f)tp(s?)://(www)?)|www)((?:[a-z0-9.-]|%[0-9A-F]{2}){3,})(?::(\\d+))?((?:\\/(?:[a-z0-9-._~!$&'()*+,;=:@]|%[0-9A-F]{2})*)*)(?:\\?((?:[a-z0-9-._~!$&'()*+,;=:\\/?@]|%[0-9A-F]{2})*))?(?:#((?:[a-z0-9-._~!$&'()*+,;=:\\/?@]|%[0-9A-F]{2})*))?(\\s*|$)
java.util.regex.Matcher m = p.matcher(content);

while (m.find()) {

//do the required action

//String matchString= m.group();

}

we can use group function of Matcher in java regx to retrieve the matched text:

A group is a pair of parentheses used to group subpatterns. For example, h(a|i)t matches hat or hit. A group also captures the matching text within the parentheses. For example,

input: abbc

pattern: a(b*)c

causes the substring bb to be captured by the group (b*). A pattern can have more than one group and the groups can be nested. For example,

pattern: (a(b*))+(c*)

contains three groups:

group 1: (a(b*))
group 2: (b*)
group 3: (c*)

The groups are numbered from left to right, outside to inside. There is an implicit group 0, which contains the entire match. Here is an example of what is captured in groups. Notice that group 1 was applied twice, once to the input abb and then to the input ab. Only the most recent match is captured. Note that when using * on a group and the group matches zero times, the group will not be cleared. In particular, it will hold the most recently captured text. For example,

input: aba

pattern: (a(b)*)+ group 0: aba group 1: a group 2: b

Group 1 first matched ab capturing b in group 2. Group 1 then matched the a with group 2 matching zero bs, therefore leaving intact the previously captured b.

Note: If it is not necessary for a group to capture text, you should use a non-capturing group since it is more efficient. This example demonstrates how to retrieve the text in a group.

CharSequence inputStr = "abbabcd";
String patternStr = "(a(b*))+(c*)";

// Compile and use regular expression
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(inputStr);
boolean matchFound = matcher.find();

if (matchFound) {
    // Get all groups for this match
    for (int i=0; i<=matcher.groupCount(); i++) {
        String groupStr = matcher.group(i);
    }
}

Sources: www.vogella.de www.exampledepot.com java.sun.com

Regular Expression Pocket Reference Regular Expressions for Perl, Ruby, PHP, Python, C, Java and .NET (Pocket Reference (O’Reilly)) copy

FYI: Everything inside of an aui:script block that contains a “use” attribute is called asynchronously, so it could fire right away (if the resources are on the page) or if the network resolution is taking a long time, it could execute later on.

Bellow is an example:

alert('not "using" any modules, Im fired right away');
alert('"using" aui-io, Im fired when its ready');

So we make sure never to define a function inside of an aui-script block that has a “use” attribute, unless we’re creating another module to be used.

But then how do you define a function that uses a module?
Luckily, we can use Liferay.provide.

For simplicity here I have used two field which will indicated the checked and unchecked value of checkboks and can easily get this value on action class, like bellow:

<aui:input name="addCommIds" type="hidden" value="" />
<aui:input name="removeCommIds" type="hidden" value="" />

Bellow given the aui:script code:


Liferay.provide(
window,
'saveEntry',
function() {
document.fm.addCommIds.value = Liferay.Util.listCheckedExcept(document.fm, "allRowIds");
document.fm.removeCommIds.value = Liferay.Util.listUncheckedExcept(document.fm, "allRowIds");
submitForm(document.fm);
},
['liferay-util-list-fields']
);

NB: listCheckedExcept is a javascript function
we can simply call this function as bellow:

<aui:button onClick="<%= renderResponse.getNamespace() + "saveEntry();" %>"value="save" />

Source

I have not found any direct way to get ajax support with spring MVC. I got the same feature using jQuery , Spring MVC , XStream, Jettison

My problem was needed to show sate, city and county information against a given zip code in a portion of page without refreshing the page. So ajax is the best candidate here. But problem was I have not found any direct way to work ajax with Spring MVC. In Spring3 you can do it easily using ajax library but not supported in spring MVC.

I solve the problem using jQuery , Spring MVC , XStream, Jettison. Here I have given a step by step example of ajax and Spring MVC with JSON:

The simple jsp page where needed to show the information, I have excluded the tag  include part:

<html>
<head>
<script src="<c:url value="/javascripts/jquery/jquery-1.2.6.min.js"/>"> </script>
<script src="<c:url value="/javascripts/jquery/jquery.form.js"/>"> </script>
<script type="text/javascript">
function getInfo(frm){
if (frm.bZipCode.value == "")
alert("Hey! You didn't enter anything in zip code!");
else{
$.getJSON("<c:url value="/zipInfo.htm" />",     // url
{ zipId: frm.bZipCode.value },   // request params
function(json){           // callback
$(json.zipInfo).each(function() {
frm.bState.value =this.state;
frm.bCountry.value =this.conty;
frm.bCity.value =this.city;
});
}
);
}
}
</script>
</head>
<body>
<form:form commandName="providerForm"
onsubmit="return checkCreateSPForm(this);"
enctype="multipart/form-data">
<table border=0 cellpadding=0 cellspacing=0 width=100%>
<tr bgcolor="#FFFFFF">
<td width="18%">Enter Zip code and click on Info button to get related information</td>
<td width="80%"> <input type="text" name="bZipCode" id="bZipCode" size="25" maxlength="100" >
<input type="button" onclick="getInfo(this.form)" value="Get Info"/> </td> </tr>
<tr bgcolor="#FFFFFF">
<td width="18%">State</td>
<td width="80%"><input type="text" name="bState" id="bState" size="40" maxlength="100"> </td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="18%">Business County</td>
<td width="80%"><input type="text" name="bCountry" id="bCountry" size="40" maxlength="100"> </td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="18%">Business City</td>
<td width="80%"><input type="text" name="bCity" id="bCity" size="40" maxlength="100"> </td>
</tr>
<tr>
<td> <input type="submit" value="Submit"></td>
</tr>
</table>
</form:form>
</body>
</html>

Now going to the code where the server returns JSON data to the browser. Starting on the server side, we will see how we can use Spring MVC along with XStream and Jettison to serve up JSON data.

Bellow given the Spring MVC controller code:

@Controller
public class AdminController extends SimpleFormController{
@Autowired
IProviderService SPService;
@RequestMapping("/zipInfo.htm")
public ModelAndView years(@RequestParam("zipId") Long zipId) {
ModelAndView mav = new ModelAndView(JsonView.instance);
//getting zipInfo from database
ZipInfo zipInfo=SPService.getZipInfoById(String.valueOf(zipId));
if(zipInfo==null){
zipInfo=new ZipInfo();
zipInfo.setCity("city");
zipInfo.setConty("conty");
zipInfo.setState("state");
}
mav.addObject(JsonView.JSON_ROOT, zipInfo);
return mav;
}
}

The @Controller annotation tells Spring MVC to use this class as a controller

The @RequestMapping annotation maps the request URL to the handler method

A ModelAndView object is created with a view name of “mav” which will get mapped to jsp page

zipInfo load from database against the provided zipId and added to the Model And View

The @RequestMapping annotation maps the request URL to the handler method

The @RequestParam annotation maps a request parameter to a method argument

This ModelAndView is created using a simple JSON-rendering View class that I wrote called JsonView. Spring MVC makes is quite easy to write custom views, and JsonView is where XStream gets hooked in.

In summary, the controller responds URL, “zipInfo.htm”. It returns ZipInfo object as the response to the “zipInfo.htm” URL. Let’s take a look at the JsonView class, which renders the JSON result for the “zipInfo.htm” request:

import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.View;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
public class JsonView implements View {
public static final JsonView instance = new JsonView();
public static final String JSON_ROOT = "root";
// This instance of XStream is thread-safe. XStream is not
// thread-safe if auto-detection of annotations is used.
private XStream xstream = new XStream(new JettisonMappedXmlDriver());
private JsonView() {
// in a large project, listing every class with XStream
// annotations is not practical. 2 alternatives are:
// * traversing the classpath using a specified root package
// and calling processAnnotations
// * enabling annotation auto-detection, but then the XStream
// instance is not thread-safe
xstream.processAnnotations(ZipInfo.class);
}
public String getContentType() {
return "text/html; charset=UTF-8";
}
@SuppressWarnings("unchecked")
public void render(Map model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Object root = model.get(JsonView.JSON_ROOT);
if (root == null) {
throw new RuntimeException("JSON root object with key '"
+ JsonView.JSON_ROOT + "' not found in model");
}
PrintWriter writer = response.getWriter();
// even though the following method is "toXML" XStream is configured
// to use Jettison to output JSON instead
String json = xstream.toXML(root);
System.out.println("json: " + json);
writer.write(json);
}
}

Source

Liferay provides “LocalServiceUtil” to interact with database, we can do the common and basic functionality using these LocalServiceUtil classes. However sometimes we may need to run complex quires beside the common service like filtering out from result list or directly getting the data by certain criteria etc. Liferay provides several factory classes in this case to make our life easier, listed bellow:

DynamicQueryFactoryUtil
OrderFactoryUtil
ProjectionFactoryUtil
PropertyFactoryUtil
RestrictionsFactoryUtil

Here I will provide a example on how to use DynamicqueryFactoryUtil to make dynamic query.

ClassLoader cl = PortalClassLoaderUtil.getClassLoader();
DynamicQuery dqi = DynamicQueryFactoryUtil.forClass(
AnnouncementsEntry.class, cl);


Criterion crit = PropertyFactoryUtil.forName("title").eq(title);
dqi.add(crit);


crit = PropertyFactoryUtil.forName("displayDate").eq(displayDate);
dqi.add(crit);

try {
results = AnnouncementsEntryLocalServiceUtil.dynamicQuery(dqi);

} catch (SystemException e) {
e.printStackTrace();
}

classloader ensure that the implementation class can be loaded . Propertyfactoryutil may used for checking certain feature like equality, between, empty, nonempty etc ie. Projection/ restriction. Actually PropertyFactoryUtil return a Property instance that allows us to create Criterion objects and to assign them in DynamicQuery.
Reference Link

Load user specific preference:

com.liferay.portal.model.Layout layout = ((com.liferay.portal.theme.ThemeDisplay)themeDisplay).getLayout();
javax.portlet.PortletPreferences portletSetup = com.liferay.portlet.PortletPreferencesFactoryUtil
.getLayoutPortletSetup(layout, "portlet_id");


try {
portletSetup.setValue("key", "value");
portletSetup.getValue("key", "default value");
} catch (ReadOnlyException e1) {
e1.printStackTrace();
}

here themeDisplay is user specific themeDispaly as a result it load user specific preference.

Load global preference:

javax.portlet.PortletPreferences portletSetup = actionRequest.getPreferences();


try {
portletSetup.setValue("key", "value");
portletSetup.getValue("key", "default value");
} catch (ReadOnlyException e1) {
e1.printStackTrace();
}

here actionRequest may be javax.portlet.RenderRequest or javax.portlet.ActionRequest or javax.portlet.PortletRequest

You need to set the following properties in liferay-portlet.xml or in case of overridden in ext liferay-portlet-ext.xml, if want to set company wise/ global preference for portlet:

<preferences-company-wide>true</preferences-company-wide>
<preferences-unique-per-layout>false</preferences-unique-per-layout>

If this type of error comes in development; actually I got this exception in liferay development and by googling found this occur for lucene storage error. So first what I have done: changed the lucene.store.type=file to lucene.store.type=jdbc in portal.properties. You may override it in portal-ext.properties of ext without modifying directly in liferay code.

After that exception may throw like bellows:

Check Lucene directory failed for 0
java.lang.NullPointerException
at org.apache.lucene.store.jdbc.support.JdbcTable.setName(JdbcTable.java:183)
at org.apache.lucene.store.jdbc.support.JdbcTable.<init>(JdbcTable.java:75)
at org.apache.lucene.store.jdbc.support.JdbcTable.<init>(JdbcTable.java:69)
at org.apache.lucene.store.jdbc.JdbcDirectory.<init>(JdbcDirectory.java:121)
at com.liferay.portal.search.lucene.IndexAccessorImpl._getLuceneDirJdbc(IndexAccessorImpl.java:318)
at com.liferay.portal.search.lucene.IndexAccessorImpl.getLuceneDir(IndexAccessorImpl.java:161)
at com.liferay.portal.search.lucene.IndexAccessorImpl._checkLuceneDir(IndexAccessorImpl.java:188)
at com.liferay.portal.search.lucene.IndexAccessorImpl.<init>(IndexAccessorImpl.java:77)
at com.liferay.portal.search.lucene.LuceneHelperImpl._getIndexAccessor(LuceneHelperImpl.java:287)
at com.liferay.portal.search.lucene.LuceneHelperImpl.deleteDocuments(LuceneHelperImpl.java:168)
at com.liferay.portal.search.lucene.LuceneHelperUtil.deleteDocuments(LuceneHelperUtil.java:165)
at com.liferay.portal.search.lucene.LuceneIndexWriterImpl.deletePortletDocuments(LuceneIndexWriterImpl.java:85)
at com.liferay.portal.kernel.search.messaging.SearchWriterMessageListener.doReceive(SearchWriterMessageListener.java:75)
at com.liferay.portal.kernel.search.messaging.SearchWriterMessageListener.receive(SearchWriterMessageListener.java:41)
at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:73)
at com.liferay.portal.kernel.messaging.ParallelDestination$1.run(ParallelDestination.java:68)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)

Here you need to change little in database connection URL:

jdbc.default.url=jdbc:mysql://localhost/DBName?emulateLocators=true&useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false

Added emulateLocators=true in database URL; Also don’t forget to clean database. now running ok for me 🙂

If error comes like bellow:

org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out:
at org.apache.lucene.store.Lock.obtain(Lock.java:70)
at org.apache.lucene.index.IndexWriter.init(IndexWriter.java:598)
at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:410)
at com.liferay.portal.lucene.IndexWriterFactory.getWriter(IndexWriterFactory.java:182)
at com.liferay.portal.lucene.LuceneUtil.getWriter(LuceneUtil.java:285)
at com.liferay.portal.lucene.LuceneUtil.getWriter(LuceneUtil.java:279)
at com.liferay.portal.plugin.PluginPackageIndexer.addPluginPackage(PluginPackageIndexer.java:78)
at com.liferay.portal.plugin.PluginPackageIndexer.updatePluginPackage(PluginPackageIndexer.java:227)
at com.liferay.portal.plugin.PluginPackageUtil._indexPluginPackage(PluginPackageUtil.java:835)
at com.liferay.portal.plugin.PluginPackageUtil._parseRepositoryXml(PluginPackageUtil.java:987)
at com.liferay.portal.plugin.PluginPackageUtil._loadRepository(PluginPackageUtil.java:886)
at com.liferay.portal.plugin.PluginPackageUtil.reloadRepositories(PluginPackageUtil.java:612)
at com.liferay.portlet.admin.job.CheckRemoteRepositoriesJob.execute(CheckRemoteRepositoriesJob.java:47)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)

 

To solve this error delete your lucene directory, deploy all and restart server . Check your portal.properties or portal-ext.properties to figure out where this is, by default it is configured as:

lucene.dir=${liferay.home}/data/lucene/
liferay.home=${resource.repositories.root}
resource.repositories.root=${default.liferay.home}

Suppose I have a many to one relation between Task and User, there also a one to one relation between User and UserRegistration

In Task there is a collection like bellow:

<many-to-one name="createBy" column="CRE_BY" not-null="true"/>

In User there is a collection like bellow:

<many-to-one name="userRegInfo" column="USER_REG_ID" not-null="true" cascade="all" unique="true" />

Now if I want to access information from TaskInfo may need to join UserInfo with TaskInfo and as a result may need to join UserRegInfo and UserInfo to get specific data.

This can be done following way:


DetachedCriteria dCriteria =DetachedCriteria.forClass(TaskInfo.class);
- - - - - - - - -  - - - - - - - - -  - - - - - - - - - dCriteria.setFetchMode("createBy",FetchMode.JOIN).

setFetchMode("createBy.userRegInfo", FetchMode.JOIN);
- - - - - - - - -  - - - - - - - - -  - - - - - - - - - - -

If source named ExcelExample then directory structure will be like bellow:

servlet directory structure in tomcat

servlet directory structure in tomcat

Need to add the following text in server.xml to run on tomcat:

  <Context path="/ExcelExample"
          docBase="webapps/ExcelExample"
          crossContext="true"
          debug="0"
          reloadable="true"
          trusted="false" >
  </Context>

Source

If you want to export javadoc from source code, you do it easily by the help of eclipse. Select Project in Eclipse and got to Project->Generate Javadoc and follow the instruction to save html files in defined location.

java doc

eclipse java doc

April 2024
S M T W T F S
 123456
78910111213
14151617181920
21222324252627
282930  

RSS Hima’s Blog

  • An error has occurred; the feed is probably down. Try again later.