Tuesday, January 15, 2013

Having Multiple Instances for Liferay Portlet

Use: For allowing to add more than one portlet instance on same page (where each portlet instance has uniquely generated portlet-id).

How to:
a. Update "liferay-portlet.xml" configuration as:
 <portlet>  
    ...  
   <instanceable>true</instanceable>  
   <!-- <scopeable>true</scopeable>  
   <ajaxable>false</ajaxable> -->  
    ...  
 </portlet>  
b. In JSP files (eg. view.jsp) append unique portlet-id to (AJAX) URL parameters as:
 "<portlet:namespace />myparam1=" + someparamval;  
c. In Java files get the unique portlet-id as:
 public String render(PortletConfig config, RenderRequest renderRequest, RenderResponse renderResponse) {  
   ...  
   System.out.println("Portlet Id:" + PortalUtil.getPortletId(renderRequest));  
   System.out.println("Portlet Namespace:" + PortalUtil.getPortletNamespace(PortalUtil.getPortletId(renderRequest)));  
   ...  
 }  
Points to be considered:
a. URL parameters may conflict
b. Any kind of refresh may affect all instances together
c. Preferences may conflict
d. If preference names are modified then existing Production user preference data will be lost
e. Overall performance may deteriorate

Effect:
a. If a normal URL parameter say "param1"  would need to be sent from jsp / js as "portletuniqueid_param1"
b. If a normal URL parameter say "param1"  would need to be read in java as "portletuniqueid_param1"

Friday, September 7, 2012

SQL & Liferay Dynamic Queries Compared...

SQL 1:
select * from mycustomtable where status='Pending' and userId=10122 order by modifiedDate desc, requestId asc;
DQ 1:
 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(MyCustomTable.class);  
 dynamicQuery.add(PropertyFactoryUtil.forName("status").eq("Pending");  
 dynamicQuery.add(PropertyFactoryUtil.forName("userId").eq(10122);  
 Order defaultOrder = OrderFactoryUtil.desc("modifiedDate");  
 Order secondOrder = OrderFactoryUtil.asc("requestId");  
 dynamicQuery.addOrder(defaultOrder);  
 dynamicQuery.addOrder(secondOrder);  

SQL 2:
select * from mycustomtable where (subject like '%Test Subject%') and ((create_date between '10/08/2012' and '10/09/2012') or (status='Pending'));
DQ 2:
 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(MyCustomTable.class);  
 Criterion criterion = null;  
 criterion = RestrictionsFactoryUtil.like("subject", StringPool.PERCENT + "Test Subject"+ StringPool.PERCENT);  
 criterion = RestrictionsFactoryUtil.and(criterion, RestrictionsFactoryUtil.between("create_date",10/08/2012,10/09/2012));  
 criterion = RestrictionsFactoryUtil.or(criterion, RestrictionsFactoryUtil.eq("status", "Pending"));  
 dynamicQuery.add(criterion);  

SQL 3:
select max(col1) from mycustomtable where status='Pending';
DQ 3:
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(MyCustomTable.class);  
 dynamicQuery.add(PropertyFactoryUtil.forName("status").eq("Pending");  
 dynamicQuery.setProjection(ProjectionFactoryUtil.projectionList().add(Projections.max("col1"));

SQL 4:
 select count(entryId) from mycustomtable group by userId;
DQ 4:
 DynamicQuery query = DynamicQueryFactoryUtil.forClass(MyCustomTable.class)  
   .setProjection(ProjectionFactoryUtil.projectionList()  
   .add(ProjectionFactoryUtil.groupProperty("userId"))  
   .add(ProjectionFactoryUtil.count("entryId")));  

SQL 5:
 select count(*) from mycustomtable where status='Pending';
DQ 5:
 DynamicQuery query = DynamicQueryFactoryUtil.forClass(MyCustomTable.class)  
   .add(Property.forName("status").eq('Pending'))  
   .setProjection(Projections.rowCount());  

SQL 6:
 select msct.somecol from myfirstcustomtable mfct, mysecondcustomtable msct  
   where mfct.matchcol1=msct.matchcol1 and mfct.status='Pending'  
   order by othercol desc;  
DQ 6:
 DynamicQuery dq1 = DynamicQueryFactoryUtil.forClass(  
   MyFirstCustomTable.class, "mfct")  
   .setProjection(ProjectionFactoryUtil.property("somecol"))  
   .add(PropertyFactoryUtil.forName("mfct.matchcol1").eqProperty("msct.matchcol1"))  
   .add(PropertyFactoryUtil.forName("mfct.status").eq("Pending"));  
 DynamicQuery dq2 = DynamicQueryFactoryUtil.forClass(  
   MySecondCustomTable.class, "msct")  
   .add(PropertyFactoryUtil.forName("msct.msctPK").in(dq1))  
   .addOrder(OrderFactoryUtil.desc("msct.othercol"));  

Steps for building a custom SQL finder:
1. Create a new finder called CompetenceLevelFinderImpl in the /generated/service/persistence directory.
2. Let this class extend BasePersistence.
3. Now do a 'build-service' on the project.
4. The ServiceBuilder autogenerates the following two extra files : CompetenceLevelFinder.java and CompetenceLevelFinderUtil.java
5. Now open the CompetenceLevelFinderImpl.java file and let this class extend the CompetenceLevelPersistenceImpl class and implement CompetenceLevelFinder. (Assumed that the CompetenceLevel entity is defined in the service.xml and that the needed classes are also autogenerated by ServiceBuilder.)
6. Now add the needed functionality to the CompetenceLevelFinderImpl class and do a build-service.
7. You can now use the added functionality.

Useful Links:
http://www.liferay.com/community/wiki/-/wiki/Main/Service+Builder+Finders

Sunday, January 22, 2012

CSS / HTML - drawing a rectangle with round corners

This was my first encounter with CSS3 and it was pretty interesting too.

Following
CSS / HTML code-snippet helps drawing a rectangle with round corners:

Code:


Output:



The key to make it browser independent is to make it work on older versions of Internet Explorer. For this you will need an .htc file. This file contains a bunch of javascript functions that will ensure round edges to an html element like div or td.

Wednesday, June 2, 2010

Difference between TRUNCATE & DELETE?

TRUNCATE:
1. Faster - does its work in single execution by
deallocating the data pages used by the table and reducing
the resource overhead of logging the deletions, as well as
the number of locks acquired.
2. Is DDL command
3. Removes all data
4. Does not make entries in a LOG file
3. Can't be rolled-back
4. Can't filter using WHERE clause
5. Can't call DML triggers
6. Can't ensure data consistency in case of foreign-key
references
7. Resets the IDENTITY back to the SEED

DELETE:
1. Slower - does its work by deleting rows one at a time,
logging each row in the transaction log, maintaining log
sequence number (LSN) information and consuming more
database resources and locks.
2. Is DML command
3. Removes data row-by-row
4. Makes entry per row in a LOG file
3. Can use COMMIT or ROLLBACK
4. Can filter using WHERE clause
5. Can call DML triggers
6. Ensures data consistency in case of foreign-key references
7. Does not reset the IDENTITY

Tuesday, June 1, 2010

MySQL to HSQL Migration Tips

Some of the important points that I had jotted down while working on MySQL to HSQL Migration:

1. HSQL does not support the BLOB. We can use LONGVARBINARY. That is, an HSQLDB Blob object does not contain a logical pointer to SQL BLOB data; rather it directly contains a representation of the data (a byte array). Similarly, for 'mediumblob' we can use VARBINARY.

2. HSQL does not support the TEXT / MEDIUMTEXT. We can use LONGVARCHAR.

3. We can not create a column which is equivalent to a keyword without putting it inside escape (double) quotes. HSQL Syntax: CREATE TABLE test_table ( key_id VARCHAR(500) NOT NULL, first_col VARCHAR(50) NOT NULL, "position" BIGINT NOT NULL, third_col VARCHAR(50) NOT NULL, PRIMARY KEY (key_id) );

4. TINYINT, INT, BIGINT does not have precision support. We can not use the precision for the columns and using the data types as is without precision.

5. HSQL does not support column level privileges. UNSIGNED keyword is not supported. We can neglect this keyword.

6. HSQL does not support column level privileges. HSQL does not support the AUTO_INCREMENT. We can use IDENTITY keyword instead. An IDENTITY column is always treated as the primary key for the table (as a result, multi-column primary keys are not possible with an IDENTITY column present).

7. HSQL does not support column level privileges. HSQL (1.8.1) does not support the UNIQUE keyword in a column definition. But it does support unique constraints defined separately. HSQL Syntax: ALTER TABLE <tablename> ADD CONSTRAINT <constraintname> UNIQUE (username);

8. HSQL does not support column level privileges. HSQL does not support the DEFAULT key word in a column definition. But it does support default values to be defined separately. HSQL Syntax: ALTER TABLE <tablename> ALTER COLUMN <columnname> SET DEFAULT <defaultvalue>;

9. HSQL does not support column level privileges. HSQL does not support creation of indices using create table statement. We can create them separately. HSQL Syntax: CREATE INDEX <indexname> ON <tablename> (<columnname>, ...);

10. HSQL does not support "..IF NOT EXISTS.." clause for create table statement and “...IF EXISTS...” clause for drop table statement. We can simply attempt to create the table and catch the exception if it doesn't succeed, then coninue.

11. HSQL does not support "ENGINE, DEFAULT_CHARSET and ROW_FORMAT" options for create table statement. We will provide a work-around to support the same functionality or if not supported at all then will add our comments to the JIRA issue.

12. HSQL does not support insert statment variation such as: "INSERT INTO ... ON DUPLICATE KEY UPDATE". We will provide a work-around to support the same functionality or if not supported at all then will add our comments to the JIRA issue.

13. HSQL (1.8.1.2) does not support TRUNCATE keyword. But it is supported in versions 1.9 onwards. We can use DELETE FROM <tablename> for HSQL (1.8.1.2).

14. HSQL does not support the keyword IGNORE for insert statments.

15. We can use RAWTOHEX(str) method to test insertion of BLOB, CLOB fields. HSQL Syntax: INSERT INTO <tablename> VALUES (RAWTOHEX('SomeStringDataToBeConvertedToBinary'))

16. HSQL does not support LIMIT clause separately. But it does support the LIMIT clause within the SELECT clause itself. HSQL Syntax: SELECT LIMIT <offset> <length> <<columnname>, ... > FROM <tablename>

17. HSQL does not support statement USE <schemaname>. But it does support SET SCHEMA <schemaname> statement.

18. HSQL does not support create/drop of database. We can use create/drop schema directly. HSQL Syntax: CREATE SCHEMA <schemaname> AUTHORIZATION DBA; and DROP SCHEMA <schemaname> CASCADE;

19. HSQL does not support GRANT with wild-cards.

20. HSQL does not support “ALGORITHM=UNDEFINED DEFINER=<username> SQL SECURITY DEFINER” part for the create procedure syntax.

21. NOTE: Since HSQLDB is written in Java, it uses Java classes for its stored procs. Thus, potentially any "public static" java method can be configured as a stored procedure.
 public class HSQLAllStoredProcs {
      public static void proc_Int(Integer i1) {
      }
      public static void proc_IntInt(Integer i1, Integer i2) {
      }
      public static void proc_IntDate(Integer i1, Date d1) {
      }
      public static void proc_LongDate(Long l1, Date d1) {
      }
 }
These static java functions are called directly from the SQL language or using an alias.
CREATE ALIAS load_proc_IntDate FOR "com.mycompany.dao.sp.HSQLAllStoredProcs.proc_IntDate";
22. Datatype Mappings:

MySQL Datatype HSQL (1.8.1.2) Datatype Oracle (10 g) Datatype MS SQL 2005 Datatype
INT INT INT INT
INT(PRECISION) INT NUMBER(PRECISION) INT
VARCHAR VARCHAR VARCHAR VARCHAR
VARCHAR(PRECISION) VARCHAR(PRECISION) VARCHAR(PRECISION) VARCHAR(PRECISION)
CHAR CHAR CHAR CHAR
MEDIUMTEXT LONGVARCHAR CLOB NVARCHAR(MAX)
TEXT LONGVARCHAR CLOB TEXT
DATETIME DATETIME TIMESTAMP DATETIME
TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP
TINYINT TINYINT TINYINT TINYINT
TINYINT(PRECISION) TINYINT NUMBER(PRECISION) TINYINT(PRECISION)
BIGINT BIGINT BIGINT BIGINT
BIGINT(PRECISION) BIGINT NUMBER(PRECISION) BIGINT(PRECISION)
MEDIUMBLOB VARBINARY BLOB VARBINARY(MAX)
BLOB LONGVARBINARY BLOB VARBINARY(MAX)
BOOLEAN BOOLEAN NUMBER(1) TINYINT
BOOLEAN DEFAULT TRUE BOOLEAN NUMBER(1) DEFAULT 1 TINYINT DEFAULT 1
VARCHAR(4096) - Precision more than 4000 VARCHAR(4096) CLOB VARCHAR(4096)
UNSIGNED -- NA --
There is no discrimination between SIGNED and UNSIGNED numbers.
-- NA --
There is no discrimination between SIGNED and UNSIGNED numbers.
-- NA --
There is no discrimination between SIGNED and UNSIGNED numbers.
DEFAULT now() CURRENT_TIMESTAMP DEFAULT SYSTIMESTAMP -- NA --
We cannot set to default value for TIMESTAMP fields.
SQL Error: Defaults cannot be created on columns of data type timestamp
ON DELETE RESTRICT (while defining foreign contraint) ON DELETE RESTRICT -- NA --
Default behavior provided by Oracle
-- NA --
Default behavior provided by MS SQL
NOT NULL DEFAULT '' NOT NULL DEFAULT '' DEFAULT '' NOT NULL DEFAULT ''
TIMESTAMP DEFAULT '0000-00-00 00:00:00' CURRENT_TIMESTAMP TIMESTAMP DEFAULT SYSTIMESTAMP -- NA --
We cannot set to default value for TIMESTAMP fields.
SQL Error: Defaults cannot be created on columns of data type timestamp
BEGIN TRANSACTION -- NA --
Stored procedures are not supported using SQL syntax in HSQL.
-- NA --
Transactions are inbuilt in Oracle
BEGIN TRANSACTION

Friday, May 14, 2010

Varargs methods

Varargs methods have been introduced in Java 5, but they currently don’t have a wide diffusion and most part of the Java developers are not aware of their existence.

The vararg notation allows methods to accept a variable number of arguments and packs them into an array. This notation is not as convenient as you might like, because the arrays it creates suffer from the same issues involving reification as other arrays.

A Varargs methods is a standard Java method that can be invoked using a different number of objects as parameters. Example:
 // Method declaration  
 public void print(String... strs) {  
      for (int i = 0; i < strs.length; i++) {  
           System.out.println(strs[i]);  
      }  
 }  
 // Method call  
 print(null, "Hello", "World", "!");  
The syntax "String…" stands for "any number of objects of type string". You can manage this “strange” object as a normal array inside the method body. From the method writer point of view, a Varargs method is just a method with an array as its last argument. The real difference between this method and a standard one becomes evident when it is invoked. Note that the first argument is ignored in the declaration of the print method and if you desire you can write a method using just a Varargs parameter and nothing else.
The compiler translates
 return arithmetic.add(x, x, x);  
to
 return arithmetic.add(x, new Object[] {x, x});  
when the type is given in the method call. It is, as if it was doing the translation before making the decision of the T type.
 int testMethod (int x, int y, int z, int ... n) {}  
A method can accept "normal" parameters along with variable length parameter lists. To do this you must ensure that the variable length parameter list is declared last. Also, a method can't declare more than one varargs parameter.
SYNTAX:
 methodName (type t1, type t2, type t ... arguments) {}  
NOTE: Statements/Snippets taken from multiple posts purely for my understanding as well as jotting different experiences at a single place.

Thursday, May 13, 2010

Spring Transaction Management Facts

Spring Transaction Management Facts: (we may call it as business transactions as opposed to db transactions):

1. One of the most compelling reasons to use the Spring Framework is the comprehensive transaction support. Without a transaction, Spring can use a different connections between the two queries back-to-back.

2. Transactions are declared on the method level, but are actually bound to the running thread. It means that once you declare a method as transactional that transaction can span a called method tree of unlimited depth. That's why DAO layer is, normally, not declared as transactional.

3. Transaction is bound to the thread once you start a method declared as transactional. It stays bound to the thread until the method is finished or transaction is suspended. Non-transactional methods do not suspend transactions. Any method in the call tree that knows how to lookup the transaction bound to the thread can do it, no matter if method is marked as transactional or not.

4. Spring does not change autocommit mode or execute commits or rollbacks or do anything to your connection unless explicitly told.

5. Transactional behavior cannot work when autocommit is on.

6. Spring has capability of rollback the transaction in case of checked exceptions also but for that we need to configure the spring beans.xml accordingly.

7. For more details, please refer the link:
http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html

NOTE: Sincere thanks to all the posts that I referred to when I implemented, experienced the above important points.