Search This Blog

Sunday, 27 April 2014

Quiz on MongoDB - Part-02

## Implementation Using JAVA DRIVER
 ======================================
@NOTE: new BasicDBObject() is same as '{}' in mongo shell...given you have a hands-on exp of querrying over mongo-shell ,Keeping this in mind will help a lot while writing Code for JAVA DRIVER to query mongoDB.

 #  Java Driver: Representing Documents
How would you create a document using the Java driver with this JSON structure:
{
   "_id" : "user1",
   "interests" : [ "basketball", "drumming"]
}

new HashMap().put("_id", "user1").put(Arrays.asList("basketball", "drumming"));
new BasicDBObject("_id", "user1").append("interests", "basketball", "drumming");
new DBObject("_id", "user1").append("interests", Arrays.asList("basketball", "drumming"));
new BasicDBObject("_id", "user1").append("interests", Arrays.asList("basketball", "drumming"));          [# CORRECT #]
 ------------------------------------------------------------------------------------------------------------
# Java Driver: Insert
Do you expect the second insert below to succeed?

        MongoClient client = new MongoClient();
        DB db = client.getDB("school");
        DBCollection people = db.getCollection("people");
        DBObject doc = new BasicDBObject("name", "Andrew Erlichson")
                .append("company", "10gen");
        try {
            people.insert(doc);      // first insert
            doc.removeField("_id");  // remove the "_id" field
            people.insert(doc);      // second insert
        } catch (Exception e) {
            e.printStackTrace();
        }

No, because the _id will be a duplicate in the collection
 No, because the removeField call will remove the entire document
 Yes, because the removeField call will remove the _id key added by the driver in the first insert                        [# CORRECT #]
 Yes, because the driver always adds a unique _id field on insert.
 ------------------------------------------------------------------------------------------------------------
#  Java Driver: find, findOne, count   : 'collection.find(), collection.findOne() , collection.count()'

 In the following code snippet:
        MongoClient client = new MongoClient();
        DB db = client.getDB("school");
        DBCollection people = db.getCollection("people");
        DBObject doc;
        xxxx
        System.out.println(doc);
Please enter the simplest one line of Java code that would be needed in place of xxxx to make it print one document from the people collection.
> doc = people.findOne(); [# ANSWER #]
------------------------------------------------------------------------------------------------------------
# Java Driver: Query Criteria
Given a collection of documents with two fields -- type and score -- what is the correct line of code to find all documents where type is "quiz" and score is greater than 20 and less than 90. Select all that apply.
scores.find(new BasicDBObject("score", new BasicDBObject("$gt", 20).append("$lt", 90));
scores.find(new BasicDBObject("type", "quiz").append("score", new BasicDBObject("$gt", 20).append("$lt", 90))) [# CORRECT #] 
scores.find(new BasicDBObject("type", "quiz").append("$gt", new BasicDBObject("score", 20)).append("$lt", new BasicDBObject("score", 90))) scores.find(QueryBuilder.start("type").is("quiz").and("score").greaterThan(20).lessThan(90).get()) [# CORRECT #]
------------------------------------------------------------------------------------------------------------

#  Java Driver: field Selection 
------------------------------------------------------------------------------------------------------------
# Java Driver: Dot Notation
In the following code snippet, what do you think will happen if there exists in the collection a document that matches the query but does not have a key called "media.url"?

DBObject findOneUrlByMediaType(DBCollection videos, String mediaType) {
    DBObject query = new BasicDBObject("media.type", mediaType);
    DBObject projection = new BasicDBObject("media.url", true);
       return videos.findOne(query, projection);
}

It will throw an exception
It will return an empty document
 It will return a document containing a single field containing the document's _id   [# CORRECT #]
 There is not enough information to know
------------------------------------------------------------------------------------------------------------
#  Java Driver: Sort, Skip and Limit
Supposed you had the following documents in a collection named things.
{ "_id" : 0, "value" : 10 }
{ "_id" : 1, "value" : 5 }
{ "_id" : 2, "value" : 7 }
{ "_id" : 3, "value" : 20 }

If you performed the following query in the Java driver:
collection.find().sort(new BasicDBObject("value", -1)).skip(2).limit(1);
which document would be returned?
The document with _id=0
The document with _id=1
 The document with _id=2
 The document with _id=3
-----------------------------------------------------------------------------------------------------------
#  Java Driver: Update and Remove
In the following code fragment, what is the Java expression in place of xxxx that will set the field "examiner" to the value "Jones" for the document with _id of 1. Please use the $set operator.

        # update using $set
        scores.update(new BasicDBObject("_id", 1), xxxx);

new BasicDBObject("$set",new BasicDBObject("examiner","Jones"))

-----------------------------------------------------------------------------------------------------------
# Java Driver -- findAndModify();

------------------------------------------------------------------------------------------------------------


## MongoDB Schema Design
=======================

What's the single most important factor in designing your application schema within MongoDB?
Making the design extensible.
 Making it easy to read by a human.
Matching the data access patterns of your application. [# CORRECT #]
 Keeping the data in third normal form.

 ----------------------------------------------------------------------------------------------------------
 Living Without Transactions
Which of the following operations operate atomically within a single document? Check all that apply.
Update [# CORRECT #]
findAndModify [# CORRECT #]
$addToSet(within an update)            [# CORRECT #]
$push within an update         [# CORRECT #]
------------------------------------------------------------------------------------------------------------
# One to One Relations
What's a good reason you might want to keep two documents that are related to each other one-to-one in separate collections? Check all that apply.
Because you want to allow atomic update of both documents at once.
 To reduce the working set size of your application. [# CORRECT #]
 To enforce foreign key constraints
 Because the combined size of the documents would be larger than 16MB [# CORRECT #]

 #  One to Many Relations
When is it recommended to represent a one to many relationship in multiple collections?
Always
Whenever the many is large
Whenever the many is actually few Never

------------------------------------------------------------------------------------------------------------
# Trees
Given the following typical document for a e-commerce category hierarchy collection called categories
{
  _id: 34,
  name : "Snorkeling",
  parent_id: 12,
  ancestors: [12, 35, 90]
}
Which query will find all descendants of the snorkeling category?
db.categories.find({ancestors:{'$in':[12,35,90]}})
db.categories.find({parent_id: 34})
 db.categories.find({_id:{'$in':[12,35,90]}})
 db.categories.find({ancestors:34}) [# CORRECT #]
-----------------------------------------------------------------------------------------------------------
#  Handling Blobs
Which of the following statements are true about GridFS?
GridFS stores large blobs in a single collection by breaking up the file into multiple pieces.
Each gridFS document is given a unique filename.
GridFS stores large blobs in two collections, one for metadata and one for the blob chunks.                            [# CORRECT #]
GridFS compresses your file on disk.

Wednesday, 23 April 2014

Using DynamicQuery on multiples Entities in Liferay

Here's an example where i have used Dynamic Query to query two different Entities in Liferay .

Entity1 = ResourceBookingMapping
Entity1 = PromotionalItemsBooking
Also, see carefully the applicantsCriterion where lies the core-logic ..

Refer the complete code-extract below :
------------------------------------------------------------------------------------------------------------------------------------
List<ResourceBookingMapping> resourceBookingList = new ArrayList<ResourceBookingMapping>();
Criterion combineCriterion = null;
DynamicQuery query = DynamicQueryFactoryUtil.forClass(ResourceBookingMapping.class);
DynamicQuery applicantQuery = DynamicQueryFactoryUtil.forClass(PromotionalItemsBooking.class)
.setProjection(ProjectionFactoryUtil.property("referenceNo"))
.add(RestrictionsFactoryUtil.eq("userId", applicantId));
Criterion dateRangeCriterion = RestrictionsFactoryUtil.between("createDate",
                                                                                                new java.sql.Timestamp( date1.getTime()), 
                                                                                               new java.sql.Timestamp(date2.getTime()));
Criterion itemsCriterion = RestrictionsFactoryUtil.eq("itemId",itemId);
Criterion applicantsCriterion = PropertyFactoryUtil.forName("referenceNo").in(applicantQuery);
Criterion itemsUnionApplicantCriterion = RestrictionsFactoryUtil.and(itemsCriterion ,                                                                                                                                                                                                 applicantsCriterion);
if(applicantId>0 && itemId>0){
System.out.println(" Criterion -PromotionalItemsBooking :: itemId>0 && applicantId>0 ");
combineCriterion = RestrictionsFactoryUtil.and(dateRangeCriterion, itemsUnionApplicantCriterion);
}else if(applicantId>0){
System.out.println(" Criterion -PromotionalItemsBooking :: applicantId>0 ");
combineCriterion = RestrictionsFactoryUtil.and(applicantsCriterion, dateRangeCriterion);
query.add(combineCriterion);
}else if(itemId>0){
System.out.println(" Criterion -PromotionalItemsBooking :: itemId>0 ");
combineCriterion = RestrictionsFactoryUtil.and(itemsCriterion, dateRangeCriterion);
query.add(combineCriterion);
}else{
System.out.println(" Criterion -PromotionalItemsBooking :: only Date-Range Applicable ");
query.add(dateRangeCriterion);
}
resourceBookingList = ResourceBookingMappingLocalServiceUtil.dynamicQuery(query);
------------------------------------------------------------------------------------------------------------------------------------

Monday, 14 April 2014

Quiz on MongoDB

[  $ ,^,$lt ,$gt,$lte,$gte, $or,$and,$regex ,$in ,$all, .DOT Notation]
cursor operators : .sort({name:-1}), .limit() ,  .skip()
.update() : [ $set , $inc]
----------------------------------------------------------------------------------------------------------
#Using $or
How would you find all documents in the scores collection where the score is less than 50 or greater than 90?
db.scores.find({$or:[{score:{$lt:50}},{score:{$gt:90}}]});
----------------------------------------------------------------------------------------------------------
What will the following query do?
db.scores.find( { score : { $gt : 50 }, score : { $lt : 60 } } );
Find all documents with score between 50 and 60
Find all documents with score greater than 50
Find all documents with score less than 60        [# CORRECT #]
None of the above
[## Q/A -REASON: being a JS Obj the first list of score will be replaced by the second @JS Promt...thus in order to achieve certain effect ,we could use $AND or $gt & $lt within the same inner query ,etc]
--------------------------------------------------------------------------------------------------------
#Querrying inside Array
Which of the following documents would be returned by this query?
db.products.find( { tags : "shiny" } );

{ _id : 42 , name : "Whizzy Wiz-o-matic", tags : [ "awesome", "shiny" , "green" ] } [# CORRECT #]
 { _id : 704 , name : "Fooey Foo-o-tron", tags : [ "blue", "mediocre" ] }
 { _id : 1040 , name : "Snappy Snap-o-lux", tags : "shiny" } [# CORRECT #]
 { _id : 12345 , name : "Quuxinator", tags : [ ] }
 ---------------------------------------------------------------------------------------------------------
 #Using $in & $all
 Which of the following documents matches this query?

db.users.find( { friends : { $all : [ "Joe" , "Bob" ] }, favorites : { $in : [ "running" , "pickles" ] } } )

{ name : "William" , friends : [ "Bob" , "Fred" ] , favorites : [ "hamburgers", "running" ] }
{ name : "Stephen" , friends : [ "Joe" , "Pete" ] , favorites : [ "pickles", "swimming" ] }
 { name : "Cliff" , friends : [ "Pete" , "Joe" , "Tom" , "Bob" ] , favorites : [ "pickles", "cycling" ] }[# CORRECT #]
 { name : "Harry" , friends : [ "Joe" , "Bob" ] , favorites : [ "hot dogs", "swimming" ] }
 -----------------------------------------------------------------------------------------------------------
#Querries with Dot[.] Notation
 Suppose a simple e-commerce product catalog called catalog with documents that look like this:

{ product : "Super Duper-o-phonic",
  price : 100000000000,
  reviews : [ { user : "fred", comment : "Great!" , rating : 5 },
              { user : "tom" , comment : "I agree with Fred, somewhat!" , rating : 4 } ],
  ... }
Write a query that finds all products that cost more than 10,000 and that have a rating of 5 or better..

 db.catalog.find({price:{$gt:10000},"reviews.rating":{$gte:5}}) [# ANSWER #]
 --------------------------------------------------------------------------------------------------------
 #Querying,Cursors
 Recall the documents in the scores collection:
{
"_id" : ObjectId("50844162cb4cf4564b4694f8"),
"student" : 0,
"type" : "exam",
"score" : 75
}
Write a query that retrieves exam -type documents, sorted by score in descending order, skipping the first 50 and showing only the next 20.

 db.scores.find({type:"exam"}).sort({score:-1}).skip(50).limit(20) [# ANSWER #]
 --------------------------------------------------------------------------------------------------------
 #Counting Results
 How would you count the documents in the scores collection where the type was "essay" and the score was greater than 90?
 db.scores.count({type:"essay",score:{$gt:90}})
  ----------------------------------------------------------------------------------
 #Updating wholesale Document
 Let's say you had a collection with the following document in it:
{ "_id" : "Texas", "population" : 2500000, "land_locked" : 1 }
and you issued the query:
db.foo.update({_id:"Texas"},{population:30000000})

{ "_id" : "Texas", "population" : 2500000, "land_locked" : 1 } 
{ "_id" : "Texas", "population" : 3000000, "land_locked" : 1 }
 { "_id" : "Texas", "population" : 30000000 } [# CORRECT #]
 { "_id" : ObjectId("507b7c601eb13126c9e3dcca"), "population" : 2500000 }  
  ----------------------------------------------------------------------------------
 .update() --$set
 For the users collection, the documents are of the form
{
"_id" : "myrnarackham",
"phone" : "301-512-7434",
"country" : "US"
}

Please set myrnarackham's country code to "RU" but leave the rest of the document (and the rest of the collection) unchanged. 
 > db.users.update({"_id" : "myrnarackham"},{$set:{"country":"RU"}}) [# ANSWER #]
   ----------------------------------------------------------------------------------
.update() --$unset
 Write an update query that will remove the "interests" field in the following document in the users collection.

    "_id" : "jimmy" , 
    "favorite_color" : "blue" , 
    "interests" : [ "debating" , "politics" ] 
}
 > db.users.update({"_id":"jimmy"},{$unset:{"interests":1}}) [# ANSWER #]
Further u can use the .find() mthd to verify the same 
> db.users.find({"_id" : "jimmy"})
{ "_id" : "jimmy", "favorite_color" : "blue" }
   ----------------------------------------------------------------------------------
 .update() -- USING $push, $pop, $pull, $pushAll ,$pullAll ,$addToSet
  db.array.update({"id:0"},{$push:{"a":55}})  [# INCORRECT #]
  db.array.update({"id":0},{$push:{a:55}})  [# CORRECT #]
-----------------------------------
 Suppose you have the following document in your friends collection:
{ _id : "Mike", interests : [ "chess", "botany" ] }

What will the result of the following updates be?
db.friends.update( { _id : "Mike" }, { $push : { interests : "skydiving" } } );
db.friends.update( { _id : "Mike" }, { $pop : { interests : -1 } } );
db.friends.update( { _id : "Mike" }, { $addToSet : { interests : "skydiving" } } );
db.friends.update( { _id : "Mike" }, { $pushAll: { interests : [ "skydiving" , "skiing" ] } } );

A> { _id : "Mike", interests : ["botany","skydiving","skydiving","skiing" ] } [# ANSWER #]
   ----------------------------------------------------------------------------------
#  .update() :-- Upserts {upsert:true}
upsert = update(if record foound) else insert the same [thts wht i make out of this.. ;-) ]
After performing the following update on an empty collection
db.foo.update({username:'bar'}, {'$set':{'interests':['cat', 'dog']}}, {upsert: true} );

What could be the state of the collection.
{ "_id" : ObjectId("507b78232e8dfde94c149949"), "interests" : [ "cat", "dog" ]}
 {"interests" : [ "cat", "dog" ], "username" : "bar" } 
 {} 
 { "_id" : ObjectId("507b78232e8dfde94c149949"), "interests" : [ "cat", "dog" ], "username" : "bar" } [# CORRECT #]
   ----------------------------------------------------------------------------------
 Multi-update  db.collection_name.update({},{$set:{}}{multi:true})
 Recall the schema of the scores collection:

{
"_id" : ObjectId("50844162cb4cf4564b4694f8"),
"student" : 0,
"type" : "exam",
"score" : 75
}
Give every document with a score less than 70 an extra 20 points.
> db.scores.update({score:{$lt:70}},{$inc:{score:20}},{multi:true}) [# ANSWER #]
   ----------------------------------------------------------------------------------
.remove()  works on any collection , similar to .find() method...ie unless you specify wch document to remove inside a collection it will remove all one-by-one..
 Recall the schema of the scores collection:
{
"_id" : ObjectId("50844162cb4cf4564b4694f8"),
"student" : 0,
"type" : "exam",
"score" : 75
}
Delete every document with a score of less than 60. 
 > db.scores.remove({score:{$lt:60}})
   ----------------------------------------------------------------------------------
# getLastError
 d.runCommand({getLastError:1}) --will let u know whether the last DB-Operation failed or ws successfull
   ----------------------------------------------------------------------------------

Wednesday, 22 January 2014

org.eclipse.wst.xsl.jaxp.debug.invoker.TransformationException: No embedded stylesheet instruction for file :


Recently i faced this Exception while working on a basic spring example...later to my surprize it turned out to be one stupid experience ;-) ...thus thought of sharing the same with an intent that it could save someone else's time...


org.eclipse.wst.xsl.jaxp.debug.invoker.TransformationException: No embedded stylesheet instruction for file: file:/F:/Projects_Spring/demoProject_dec22/src/mySpring.xml at org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker.transform(JAXPSAXProcessorInvoker.java:225) at org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker.transform(JAXPSAXProcessorInvoker.java:186) at org.eclipse.wst.xsl.jaxp.debug.invoker.internal.Main.main(Main.java:73)
Caused by: org.eclipse.wst.xsl.jaxp.debug.invoker.TransformationException: No embedded stylesheet instruction for file: file:/F:/Projects_Spring/demoProject_dec22/src/mySpring.xml at org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker.transform(JAXPSAXProcessorInvoker.java:214) ... 2 more



It's an Eclipse bug, I've noticed it too. Make sure that you're running the right Eclipse Runtime config (i.e. if you're clicking on the little green "Play" button on the top, thinking it will re-run the last (valid) Runtime you've ran, re-check (by clicking on the down arrow next to it) to make sure no new Runtime has been created).
What I've noticed it that even though I create a perfectlly valid run-time pointing to a Java main class and everyting, which I run a few times and all is ok, after a while, if I select an xml file (because I wanted to edit it for example) and then leave it selected as I click on my run button, Eclipse will create a new XSLT Transformation run time for that xml file and try to run it, failing with the exception you report. The solution is to erase that run time, make sure I have no xml file selected, and re-run the correct run time.

Tuesday, 17 December 2013

Creating & Using a language.properties for your custom portlet





STEP:1 Create a Package named-'content' under the.. '/docroot/WEB-INF/src'
Note: Create a Package and not a folder. [i did that mistake for the first time ;-)]

STEP:2 now create a file named - '/content/language.properties' under the content folder created above..

STEP:3 now to recognize this file @ portlet-level you need to make an entry in the 'portlet.xml' file present under the -'/docroot/WEB-INF/portlet.xml'
Add the properties file entry in this file using the resource-bundle tag as following :-
--------------------------------------------------------------------
<resource-bundle>content.language</resource-bundle>

--------------------------------------------------------------------

Note: add this Tag @ following location for each portlet (that intends to use this language.properties file) in the portlet.xml:-
--------------------------------------------------------------------
<portlet>
    <portlet-name>portfolio</portlet-name>
    ...
   <resource-bundle>content.language</resource-bundle>
    <portlet-info>...</portlet-info>
    ...
</portlet>
--------------------------------------------------------------------
Note: Also , the correct entry format is : <resource-bundle>content.language</resource-bundle>
often mistaken with --
<resource-bundle>language</resource-bundle>  OR
<resource-bundle>language.properties</resource-bundle>  OR
<resource-bundle>content.language.properties</resource-bundle>

To populate a jQuery-DataTable by passing JSON Response(JSonArray) as parameter.

Recently, i came across a Reqirement where i need to populate datatable(i used jQuery-DataTable) by passing JSON array as input parameter.
For example , i had a JSON ajax call which returns me a JSON array data,i would like to populate datatable with this JSON array,
 i know i can do AJAX call from datatable itself, but i would like to explore this option of getting data first 
and then building table using this data..

[download link -- http://datatables.net/download/]
use the following link to download the all the required JS libs/files (probably you will get a complete JQuery Datatable project ..
and you need to extract the following files from the /js folder in there..)
- dataTables.js
- dataTables.min.js
Alongwith these you will be needing -
- jquery.js
- jquery-1.10.2.min.js    as well(download and include ,incase you haven't uptill now..)

Ok, so here the input Text in my 'jsp' which will invoke the ajax-call onKeyUp -
<input id="organizationName" name="organizationName" onkeyup="doSearchAjaxCall();" type="text" value="" />

here's the JavaScript function which is responsible for making the ajax call.....
----------------------------------------------------------------------------------------------
Also, before jumping to script keep note of the Portlet-URL(required for the ajax call) ,
i created a resourceURL (given below) which will hit the serveResource in my PortletClass ..(you may create as per your requirement)
-- -- -- -- -- -- -- -- -- -- -- -- -- --
<portlet:resourceURL var="searchRequestURL">
</portlet:resourceURL>
-- -- -- -- -- -- -- -- -- -- -- -- -- --
<script>
function doSearchAjaxCall() {
 // fetching various field params from the jsp..
var acbno = jQuery("#acbno").val();    
var orgName = jQuery("#organizationName").val();
var field = jQuery("#field").val();          

//dataType:'json',
Note: mentioning dataType in the ajax-call is note required ...only 'setContentType("application/json")' is enough [set in portlet class --see complete code below]
jQuery.ajax({
type: "POST",
url: "<%= searchRequestURL.toString() %>",
data:"acbno="+acbno+"&orgName="+orgName+"&field="+field,
error: function(data) {
alert(" inside error >>> "+data);
},
success: function(data) {
//var stringResponse = JSON.stringify(data);
Note: Dont make the Mistake of converting the data-array into string before passing into datatable - as it requires data-array in json form only..
//alert("data stringify = >>>> "+stringResponse);
// console.log("success data>>  "+data);
// pass the data-array obtained in success-fn to another js fn created -'loadDataTable()' which will futher //populate the Datatable..
loadDataTable(data);          // custom -function Call

}
});
 }

  function loadDataTable(data){

  // console.log("loadDataTable >>  "+data);
   $("#tableId1").dataTable().fnDestroy();
var oTable = $('#tableId1').dataTable({
"aaData" : data,
"aoColumns" : [
{"sTitle" : "SammNo" },
{ "sTitle" : "OrganizationName" },
{ "sTitle" : "Field" },
{"sTitle" : "Scope" }
]
});
}
// Also, you may add the ajax call on jQuery ready as well here...see explanation below >>>
</script>

Note: aaData - 
Note: aoColumns -
Note :    $("#tableId1").dataTable().fnDestroy();   ---bcz Datatables cannot be reinitialised hence, need to destroy the existing datatable before poputaing again for consecutive ajax call for same datatable..

----------------------------------------------------------------------------------------------
 Also, you may add the ajax call on jQuery ready as well Incase you want the datatable to be populated on page load as well...
 bcz above code will populate the datatable as & when the 'onkeyup()' function is called for the input-text -'organizationName'.
 ----------------------------------------------------------------------------------------------------
jQuery().ready(function(){

var acbno = jQuery("#acbno").val();
var orgName = jQuery("#organizationName").val();
var field = jQuery("#field").val();

    jQuery.ajax({
type: "POST",
url: "<%= searchRequestURL.toString() %>",
data:"acbno="+acbno+"&orgName="+orgName+"&field="+field,
error: function(data) {
alert(" inside error >>> "+data);

},
success: function(data) {

//console.log(" jQuery-ready >> success data>>  "+data);

loadDataTable(data);

}
});
});
------------------------------------------------------------------------------------------------------------


NOTE : STRICTLY AVOID USING 'console.log();' - This gives an error saying 'console is unDefined' in most of the IE version browsers. This error often breaks the complete JavaScript used ..In my case i wasn't able to display jQuery DataTables in IE whereas it was working  F9 in FF && Chrome..!!!
Though could use the same for debugging purpose OR incase the target browser for your application duznt includes IE (which is often not the case ) ;-)






Dynamically Creating a URL for a DLFileEntry or a File stored in Document & Media

Recently, i came across a requirement where i need to provide a view link to the various files stored in Liferay Document & Media.ie on click of these links the File(.pdf stored in our case) needs to open in a new Tab in Browser.
Hence, a url is required for that file :
I came to know that the complete URL formed is composed of the following components:
host+documents+groupId+folderId+fileTitle
where,
host - you can obtain as following- 'PortalUtil.getPortalURL(portletRequest)'
-will return something like this (http://localhost:8080/) incase of local machine..
documents - you can hardcode as this is hardly going to change in the D&M path..
groupId - you better fetch from the dlFileEntry Obj as - 'dlFileEntry.getGroupId()'
folderId - you better fetch from the dlFileEntry Obj as - 'dlFileEntry.getFolderId()'
fileTitle - you better fetch from the dlFileEntry Obj as - 'dlFileEntry.getTitle()'
- Note: Don't fetch 'dlFileEntry.getName()' instead of 'dlFileEntry.getTitle()'

Hence,
The complete url will look something like this:
 'http://localhost:8080/documents/10179/0/Flipkart-Induct-meet'

Here's how i formed this URl in my PortletClass:
------------------------------------------------------------------------------------------------------------
final String filePath_fromDM = "documents/"+dlFileEntry.getGroupId()+"/"+dlFileEntry.getFolderId()+"/"+dlFileEntry.getTitle();
System.out.println(">>>>>>  filePath_fromDM >>> = "+filePath_fromDM);
-will return something like this (documents/10179/0/Flipkart-Induct-meet) incase of local machine..

String completeFilePathUrl = StringPool.BLANK;
completeFilePathUrl = PortalUtil.getPortalURL(resourceRequest)+"/"+filePath_fromDM;
System.out.println(" >>> completeFilePathUrl () = "+completeFilePathUrl );
-will return something like this (http://localhost:8080/documents/10179/0/Flipkart-Induct-meet) incase of local machine..
------------------------------------------------------------------------------------------------------------

And, finally here how i formed a Link for this URL on click of which it will open the doc in a New-Tab..
String linkFormed = "<a href='"+scopeUrl+"' target='_blank'>View</a>" ;
Note: target="_Blank" is required only if you want to open the link in a new Browser Tab.
which you can pass in a response , use in a jsp , etc as per your requirement..


Tuesday, 10 December 2013

Custom queries in Liferay

Sometimes it is needed to perform joined queries with the Service Builder. It is not possible to do it with dynamic queries - custom queries are necessary.
This article explains how to create custom queries , i faced lot of issues when working on the same for the first time, unware for various minor concepts which were hard to be found at one-place . Thus ,decided to document my understanding of the same along withe the issues faced during implementation alongwith their fixes. Plz don't ignore the various -'Note' throughout the blog.


STEP:1 First of all create a folder with the name - "custom-sql"  under the src folder...
Note: create a folder & NOT a package .(see image below.)



STEP:2 Now create a file- "default.xml" in this custom-sql folder...(Though you can write your sql-querries over here as well , but its always a good practice to write your qurries in
a diff .xml file & map that file int this default.xml)
Add something like this to your default.xml:
---------------------------------------------------------------------------------
 <?xml version="1.0"?>
<custom-sql>
    <sql file="/custom-sql/myProject-portal.xml" />
</custom-sql>
---------------------------------------------------------------------------------

STEP:3 Now open your 'myProject-portal.xml' , and put  all you querries here as below... each identified by a id.
Something like this :
---------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<custom-sql>
 
    <sql id="">
        <![CDATA[
Select * from user_ where firstName ="Test"
        ]]>
    </sql>
</custom-sql>

---------------------------------------------------------------------------------
STEP:4 Add the following in ur portal-ext.properties

custom.sql.configs=\
custom-sql/default.xml, \
custom-sql/default-ext.xml

---------------------------------------------------------------------------------

Step:5 Create a FinderImpl class bearing your Entity name that must extends BasePersistenceImpl.
public class CABDisplayFinderImpl extends BasePersistenceImpl<CABDisplay>{ }

Step:6 Now run the 'build-service' task.You will observe that the service-builder has generated two more files for you in '../service/persistence' under the 'docroot/WEB-INF'-namely
-CABDisplayFinder AND
-CABDisplayFinderUtil
  Now go back to your FinderImpl class and add 'implements 'CABDisplayFinder' as below and run the Build-Service task again..
---------------------------------------------------------------------------------
  public class CABDisplayFinderImpl extends BasePersistenceImpl<CABDisplay> implements CABDisplayFinder{

}
---------------------------------------------------------------------------------
Note:
Do Keep Note of these two configuration related points -
[1] Next ,you need to create a finderImpl under the "service/persistence" under the "/docroot/WEB-INF/src" && Not in 'service/persistence' under "/docroot/WEB-INF"
[2] Also , the FinderImpl must start with the name of any defined Entity in your service.xml (say - for entity-'ABC' it would be 'ABCFinderImpl' & not 'MyABCFinderImpl',etc)
This is very imp to mention as i wasted a reasonably good amount of time breaking my head on this issue, being unaware of this concept that your FinderImpl class must bear & start with the name of a defined Entity.
I did the Mistake of creating a FinderImpl with the name 'ABCDisplayFinderImpl' for an entity -'ABCDisplay_Metadata' , whereas it should be 'ABCDisplay_MetadataFinderImpl' which solved the Issue.




Monday, 9 December 2013

How to expose Liferay Service as a Soap Web Service

Having spend myself a reasonably good amount of time in various issues ,hereby , i have shared my understanding of -'How to expose Liferay Service as a Soap Web Service'

I used Liferay6.1.1 source and Plugin-SDK(liferay-plugins-sdk-6.1.1-xx) along with eclipse juno The base platform was Java1.7.x and MySQL5.1..x.
The deployment server was Liferay-bundled-JBoss GA3. (liferay-portal-jboss-6.1.30-ee-ga3-xx)

Assuming that you are already thru the following steps mentioned below :
Step 1: Setup liferay source project and tomcat/JBoss/etc
Step 2: Setup plugin SDK.
Step 3: Create the service project (say i gave the project-name as 'cab_portletname')
Step:4 Create a new liferay-service builder file (service.xml)

Now, you can expose the liferay-service to any of the available Entities (Entities you mentioned in the service.xml).
Lets say you created an entity named- 'CABDisplay' && namespace as -'CAB' as below:-
---------------------------------------------------------------------------
<namespace>CAB</namespace>
<entity name="CABDisplay" local-service="true"
remote-service="true">

<!-- Primary Key -->
<column name="SammNo" type="long" primary="true" />
<!-- Audit fields -->
<column name="OrganizationName" type="String" />
<column name="Field" type="String" />
</entity>
---------------------------------------------------------------------------
Step:5 Save this service.xml && run the 'CABDisplay-Portlet/build-service' task.(say 'ant clean build-service' from command-prompt ,etc)
If the build fails, please check if your service.xml for any syntax-error (also, check the console & act accordingly). On successful build, the ant task creates the files related to CABDisplay entity.
You can now refresh your project (F5) to see the generated files.

Step:6 Incase you wanna expose any of the default liferay-services generated for you entity(you can check the same in the your serviceImpl -say 'CABDisplayServiceImpl' in our case)
Now Add the CRUD and finder methods into your com.liferay.test.service.impl.CABDisplayServiceImpl as listed below:
---------------------------------------------------------------------------------------
public CABDisplay fetchMetadataBySammNo(long sammno){

return cabDisplayLocalService.fetchCABDisplay(sammno);
}
---------------------------------------------------------------------------------------
public CABDisplay createCabDisplay(long sammno){

return cabDisplayLocalService.createCABDisplay(SammNo);
}
---------------------------------------------------------------------------------------

Step:7 Now you need to run the 'CABDisplay-Portlet/build-wsdd' task to generate the webservices..(say 'ant build-wsdd' from command-prompt ,etc)
Now you can simply deploy the portlet

Step:8 Now, type the following composed url in the browser && check the respective web-services exposed along with thier wsdl - "http://host/portletname-portlet/api/axis"

In our case the url will be  - " http://localhost:8080/cab_portletname-portlet/api/axis " ,which will show you all the services exposed for this respective Portlet..

where, you can check the value of 'cab_portletname-portlet' from the following locations in case of JBoss App Server "jboss-7.1.1\standalone\deployments\" &&
 "tomcat-7.x.x\webapps\" folder in case of TOMCAT App Server.

Step:9 hence, you have successfully exposed your custom liferay-services avaliable as a web service. Now in case you wanna consuming the same-- you can simply build a client using the above wsdl and consume the same...!!! ;-)

Monday, 25 November 2013

How to check the INTERNET & GPS connection in Android


----------------------------------------------------------------------------------------------------
ConnectivityManager only give information of the connection (WiFi, mobile, WiMax, etc) and if it is connected or not.

public boolean isGPSEnabled(){

LocationManager lm;
boolean GPS_Status =false;
boolean gps_enabled = false;
String title,message="";
try{
lm = (LocationManager)this.getSystemService(LOCATION_SERVICE);
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}catch(Exception e){
e.printStackTrace();
}

if(gps_enabled){
GPS_Status = true;
title="GPS ENABLED";
message ="GPS is  enabled.";
GPSChecker.showAlertDialog(this, title, message);
}else{
title="GPS Disabled";
message ="GPS is not enabled.Please TurnOn the GPS";
GPSChecker.showAlertDialog(this, title, message);
}
return GPS_Status;
}

----------------------------------------------------------------------------------------------------


/*
* This method does check-  ARE WE CONNECTED TO THE NET
*/
public final boolean isInternetOn()
{
String title,message="";
boolean connected = false;
ConnectivityManager connec = (ConnectivityManager)
   getSystemService(Context.CONNECTIVITY_SERVICE);

 if (connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED ||
 connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED ){

 // MESSAGE TO SCREEN FOR TESTING (IF REQ)
 title="Internet ENABLED";
 message ="Internet is  enabled.";
 GPSChecker.showAlertDialog(this, title, message);
 connected = true;

 }else if ( connec.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED
 ||  connec.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED  ){

 connected =  false;
 title="Internet DISABLED";
 message ="Internet is  disabled.";
 GPSChecker.showAlertDialog(this, title, message);
 }
 return connected;
}


----------------------------------------------------------------------------------------------------

Tuesday, 19 November 2013

Configuring Liferay 6.1 CE GA3 on JBoss-7.1.1 -ee-ga3

Incase you are going to setup -" liferay-portal-jboss-6.1.30-ee-ga3" , probably this blog can be of some help..as hereby i put aal my findings & steps i followed to successfully configure the same..



Few of the LINKS Followed ::


1>> Starting Server :
 Start the extracted server >> now goto  the following path -”D:\PROJECTS\Scali\liferay-JBOSS_HOME-ga3\jboss-7.1.1\bin” and double click the standalone.bat [for Windows] or you can start the same .bat file from cmd as well by going to the respective path .It will start the Server @ localhost:8080 by default.
If Its Not Started --check for the respective Error @console.
Note: Check your jdk version .Incase you are using Jboss 7.x.x its advised to use jdk7 and like wise.


2>>Incase of EE :
now you can see the deploy folder @ following path - “D:\myWorkspace\liferay-JBOSS_HOME-ga3\”  ,wch wasnt thr untill you’ll start the server atleast once. Since using an EE , need to attach a  license key [wch you can register @ liferay.com and get your trial/etc license key] , now Paste your Licence- xml file here---it will be auto deployed.Refresh the portal (default localhost:8080) --you’ll see the Basic Config page. Config ur Database here and proceed.


3>> Configuring MYSQL:
Incase you wanna configure -’MySQL’ …. copy the “mysql-connector-java-3.0.9.jar” @ following location of ur Jboss_Home-
D:\PROJECTS\Scali\liferay-JBOSS_HOME-ga3\jboss-7.1.1\modules\com\liferay\portal\main
also you need to update the module.xml present @ same loc --communicating to jboss tht u’re interested in using this resource [mysql jar ]. RESTART your Server now..


Issues Faced :
  • 08:56:20,986 INFO  [stdout] (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1) 08:56:20,982 WARN  [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolTh
read-#1][BasicResourcePool:1841] com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@285dec -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying
to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (3). Last acquisition attempt exception:
08:56:21,015 INFO  [stdout] (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1) java.sql.SQLException: Unable to connect to any hosts due to exception: java
.lang.ArrayIndexOutOfBoundsException: 40
i was using mysql jar -- ’mysql-connector-java-3.0.9.jar’ ...later used a higher version jar as this one was to Old ..so i used mysql-connector-java-3.0.17-ga-bin.jar  [Advised to use any jar of versdion >=3.0.15 ]


Issues Faced :   Another Mistake i did while Configuring mysql was to replace the hsql.jar entry with the mysql-connector-java..jar  in the module.xml.  Dont Do that as the hsql.jar is still required while deploying the ROOT.war portlet (default portlet). See below extract from module.xml for better understanding..



Don’t replace the resource-root entry of - hsql.jar with that of ‘mysql-connector-java.x.x.jar ...Instead Add a new resource-root entry ….
<resources>
<resource-root path="mysql-connector-java-3.0.17-ga-bin.jar" />      [NEW ENTRY]
      <resource-root path="hsql.jar" />
       <resource-root path="jtds.jar" />
       
       <resource-root path="portal-service.jar" />
       <resource-root path="portlet.jar" />
       <resource-root path="postgresql.jar" />
   </resources>


4>> Deploying a Portlet :::
InCase of DIRECT- DEPLOYMENT ::
You can drop your portlet war file directly @ following loc --
“D:\PROJECTS\Scali\liferay_JBoss_Home-ce-ga3\deploy“..If the server is started it’ll Autodeploy.  


[Also to Mention ,Many a blogs advocate creating a blank file along with your war file at this location say: your war file is ABC.war the create a file named ABC.war.dodeploy and drop @
{D:\Workspace\liferay-JBOSS_HOME-ga3\jboss-7.1.1\standalone\deployments} loc ,BUT incase you try … Its will give the following exceptions @ console..


:26:13,888 WARN  [org.jboss.as.ee] (MSC service thread 1-1) JBAS011006: Not installing optional component com.liferay.taglib.ui.AssetCategoriesSummaryTag due to exception : java.lang.ClassNotFoundException: com.liferay.taglib.ui.AssetCategoriesSummaryTag from [Module "deployment.ABC-portlet-6.1.1.1.war:main" from Service Module Loader]
     at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190) [jboss-modules.jar:1.1.1.GA]
     at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468) [jboss-modules.jar:1.1.1.GA]
     at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456) [jboss-modules.jar:1.1.1.GA]
     at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) [jboss-modules.jar:1.1.1.GA]
     at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120) [jboss-modules.jar:1.1.1.GA]
     at java.lang.Class.forName0(Native Method) [rt.jar:1.7.0]
     at java.lang.Class.forName(Class.java:264) [rt.jar:1.7.0]
     at org.jboss.as.server.deployment.reflect.DeploymentClassIndex.classIndex(DeploymentClassIndex.java:54) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
     at org.jboss.as.ee.component.deployers.EEModuleConfigurationProcessor.deploy(EEModuleConfigurationProcessor.java:79)
     at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
     at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
     at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0]
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0]
     at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0]


:26:13,958 INFO  [org.jboss.web] (MSC service thread 1-2) JBAS018210: Registering web context: /ABC-portlet-6.1.1.1
:26:14,025 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) JBAS018559: Deployed "ABC-portlet-6.1.1.1.war"



InCase of ANT- DEPLOYMENT ::
Also, if you try to deploy using ANT (if configured properly) , you may get the same series of exceptions .
To Overcome the same -- add the following to your build.{username}.properties
--------------------------------------------------------------------------------------------------------
#
# Specify the paths to an unzipped JBoss bundle.
#


app.server.type=jboss
app.server.parent.dir=D:/PROJECTS/my_Project_name/liferay_JBoss_Home-ce-ga3
app.server.jboss.dir=${app.server.parent.dir}/jboss-7.1.1
app.server.jboss.deploy.dir=${app.server.parent.dir}/deploy
app.server.jboss.lib.global.dir=${app.server.jboss.dir}/modules/com/liferay/portal/main
app.server.jboss.portal.dir=${app.server.jboss.dir}/standalone/deployments/ROOT.war
javac.compiler = modern


auto.deploy.dir=${app.server.jboss.deploy.dir}
--------------------------------------------------------------------------------------------------------
5>> Configuring Plugins sdk :::  Here's very nice link you can refer for configuring Plugins-Sdk (In case you haven't done it uptill now)
Refer : http://techconf.wordpress.com/2012/12/30/develop-liferay-portlet-plugin-project-without-liferay-ide-support-in-eclipse-on-jboss-server/