Sunday, April 19, 2015

How to send the HTML email using Velocity template in Adobe CQ5

This post will explain the steps required to send HTML email in Adobe CQ5 using Velocity template.

Configure mail service:

Go to the Felix Console - http://localhost:4502/system/console/configMgr
Search for Day CQ Mail Service
Enter the email server details as shown below and Save the data (Here I am using Gmail server details).


Email Template:
Create the email template as html file and store it in repository - /etc/email/template/emailTemplate.html (change the path accordingly)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <body>
       Hi ${firstName} ${lastName}</br>
       This is the sample mail.
       <ul>
  #foreach( $data in $dataList )
    <li>$data</li>
  #end
       </ul>
    </body>
</html>

Add the following Maven dependencies to the POM.xml
<dependency>
  <groupId>com.day.cq</groupId>
  <artifactId>cq-mailer</artifactId>
  <version>5.4.0</version>
  <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.6.2</version>
</dependency>

Configure the below packages as part of Import-Package in POM.xml bundle plugin 

        *,
org.apache.xerces.dom;resolution:=optional,org.apache.xerces.parsers;resolution:=optional,
oracle.xml.parser;resolution:=optional, oracle.xml.parser.v2;resolution:=optional,
org.jaxen;resolution:=optional, org.jaxen.jdom;resolution:=optional,
org.apache.xml.resolver;resolution:=optional,org.apache.xml.resolver.helpers;resolution:=optional,
org.apache.xml.resolver.tools;resolution:=optional,org.apache.tools.ant.launch;resolution:=optional,
org.apache.tools.ant.taskdefs.optional;resolution:=optional,org.apache.tools.ant.util.optional;resolution:=optional,
org.apache.avalon.framework.logger;resolution:=optional,sun.misc;resolution:=optional,
sun.rmi.rmic;resolution:=optional,sun.tools.javac;resolution:=optional,org.apache.bsf;resolution:=optional,
org.apache.env;resolution:=optional,org.apache.bcel.classfile;resolution:=optional,kaffe.rmi.rmic;resolution:=optional,
com.sun.jdmk.comm;resolution:=optional,com.sun.tools.javac;resolution:=optional,javax.jms;resolution:=optional,
antlr;resolution:=optional,antlr.collections.impl;resolution:=optional,org.jdom;resolution:=optional,
org.jdom.input;resolution:=optional,org.jdom.output;resolution:=optional,com.werken.xpath;resolution:=optional,
org.apache.tools.ant;resolution:=optional,org.apache.tools.ant.taskdefs;resolution:=optional,
org.apache.log;resolution:=optional,org.apache.log.format;resolution:=optional,org.apache.log.output.io;resolution:=optional,
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Activator>com.tr.commerce.connector.activator.Activator
</Bundle-Activator>
<Import-Package>
*,
org.apache.xerces.dom;resolution:=optional,org.apache.xerces.parsers;resolution:=optional,
oracle.xml.parser;resolution:=optional, oracle.xml.parser.v2;resolution:=optional,
org.jaxen;resolution:=optional, org.jaxen.jdom;resolution:=optional,
org.apache.xml.resolver;resolution:=optional,org.apache.xml.resolver.helpers;resolution:=optional,
org.apache.xml.resolver.tools;resolution:=optional,org.apache.tools.ant.launch;resolution:=optional,
org.apache.tools.ant.taskdefs.optional;resolution:=optional,org.apache.tools.ant.util.optional;resolution:=optional,
org.apache.avalon.framework.logger;resolution:=optional,sun.misc;resolution:=optional,
sun.rmi.rmic;resolution:=optional,sun.tools.javac;resolution:=optional,org.apache.bsf;resolution:=optional,
org.apache.env;resolution:=optional,org.apache.bcel.classfile;resolution:=optional,kaffe.rmi.rmic;resolution:=optional,
com.sun.jdmk.comm;resolution:=optional,com.sun.tools.javac;resolution:=optional,javax.jms;resolution:=optional,
antlr;resolution:=optional,antlr.collections.impl;resolution:=optional,org.jdom;resolution:=optional,
org.jdom.input;resolution:=optional,org.jdom.output;resolution:=optional,com.werken.xpath;resolution:=optional,
org.apache.tools.ant;resolution:=optional,org.apache.tools.ant.taskdefs;resolution:=optional,
org.apache.log;resolution:=optional,org.apache.log.format;resolution:=optional,org.apache.log.output.io;resolution:=optional,
</Import-Package>
<Bundle-SymbolicName>email-template
</Bundle-SymbolicName>
<Bundle-Vendor>Albin</Bundle-Vendor>
<Bundle-Category>email</Bundle-Category>
<Embed-Directory>dependencies</Embed-Directory>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>

Make sure the below plugin is configured in pom.xml(to add the dependencies to bundle classpath)
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<configuration>
<instructions>
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Directory>OSGI-INF/lib</Embed-Directory>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>

Create the Email servlet:
Create a servlet to send the email with the provides details.
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.ArrayList;

import javax.jcr.Node;
import javax.jcr.Session;
import javax.mail.internet.InternetAddress;
import javax.servlet.Servlet;
import javax.servlet.ServletException;

import org.apache.commons.mail.HtmlEmail;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.mailer.MessageGateway;
import com.day.cq.mailer.MessageGatewayService;

@SuppressWarnings({ "serial" })
@Component(metatype = false)
@SlingServlet(name = "EmailServlet", description = "EmailServlet", methods = "GET", generateComponent =false, paths = "/services/EmailServlet")
@Service(Servlet.class)

public class EmailService extends SlingAllMethodsServlet
{
private static final Logger LOG = LoggerFactory.getLogger(EmailService.class);
@Reference
private SlingRepository repository;
@Reference
private MessageGatewayService messageGatewayService;
@Override
protected void doGet(SlingHttpServletRequest request,
SlingHttpServletResponse response) throws ServletException,
IOException {
String results = sendMail("albinsharp@gmail.com", "albinsharp@gmail.com");
            if (results != null && results.equalsIgnoreCase("success")) {
                   response.getWriter().write("Email Send Successfully");
            } else {
                   response.getWriter().write(results);
            }        
}
public String sendMail(String fromAddress, String toEmailAddress) {
ArrayList<InternetAddress> emailRecipients = new ArrayList<InternetAddress>();
Session session = null;
String templateLink = "/etc/email/template/mailtemplate.html";
String result="success";
try {
session = repository.loginAdministrative(null);
String templateReference = templateLink.substring(1)+"/jcr:content";

Node root = session.getRootNode();
Node jcrContent = root.getNode(templateReference);
InputStream is = jcrContent.getProperty("jcr:data").getBinary().getStream();
InputStreamReader reader = new InputStreamReader(is);
VelocityContext context = new VelocityContext();
context.put("firstName", "Albin");
context.put("lastName", "Issac");
ArrayList<String> dataList=new ArrayList<String>();
dataList.add("Test1");
dataList.add("Test2");
dataList.add("Test3");
context.put("dataList", dataList);

StringWriter swOut = new StringWriter();
Velocity.evaluate(context, swOut, "LOG", reader);
LOG.info("Email content.."+swOut.toString());
           HtmlEmail email = new HtmlEmail();
             
             emailRecipients.add(new InternetAddress(toEmailAddress));
             email.setCharset("UTF-8");
             email.setFrom(fromAddress);
             email.setTo(emailRecipients);
             email.setSubject("This is the test mail");
             email.setHtmlMsg(swOut.toString());
             MessageGateway<HtmlEmail> messageGateway =        this.messageGatewayService.getGateway(HtmlEmail.class);
             messageGateway.send(email);
             emailRecipients.clear();      
    } catch (Exception e) {
result="Error in sending Email.."+e.getMessage();
}finally
{
session.logout();
}
return result;
}
}

Saturday, April 18, 2015

How to change the SOAINFRA Schema in Oracle SOA11g?

This post will explains how to change the SOAINFRA schema in Oracle SOA 11g

Tuesday, April 7, 2015

How to enable SSH X11 forwarding in Linux?

The  X11 forwarding from putty using Xming was not working, the DISPLAY variable is not set(echo $DISPLAY) after opening the remote server session in putty(X11 forwarding is enabled in putty and also the display is specified as localhost:0.0)

The actual issue is the X11 forwarding was not enabled in remote linux server.

The following steps can be followed to enable the X11 forwarding in linux server.

Login to linux server through putty

vi /etc/ssh/sshd_config

Enable the following flags

AllowAgentForwarding yes
AllowTcpForwarding yes
X11Forwarding yes

Execute the following commands

service sshd restart

yum -y update xauth
yum -y install xauth

Now you will be able to perform X11 forwarding.

Saturday, April 4, 2015

How to craete/manage the groups and users through Java API in Adobe CQ5?


import java.io.IOException;
import java.security.Principal;

import javax.jcr.PropertyType;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.servlet.Servlet;

import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service(value = Servlet.class)
@Component(immediate = true, metatype = true)
@Properties({
@Property(name = "sling.servlet.paths", value = "/services/manageGroupsAndUsers"),
@Property(name = "service.description", value = "ManageGroupsAndUsers"),
@Property(name = "label", value = "ManageGroupsAndUsers") })

public class ManageGroupsAndUsers extends SlingAllMethodsServlet{

/**
*
*/
private static final long serialVersionUID = 1L;

@Reference
ResourceResolverFactory resolverFactory;

private static Logger logger = LoggerFactory.getLogger(ModifyCartServlet.class);

protected final void doPost(final SlingHttpServletRequest request,
final SlingHttpServletResponse response) throws IOException {

String groupName="sampleGroup";
String userName="sampleUser";
String password="sampleUser";

ResourceResolver adminResolver = null;
Session adminSession=null;
try {
      adminResolver = resolverFactory.getAdministrativeResourceResolver(null);
      adminSession = adminResolver.adaptTo(Session.class);
      final UserManager userManager= adminResolver.adaptTo(UserManager.class);
           
     if(null==userManager.getAuthorizable(groupName)){
   
     Group group=userManager.createGroup(groupName,new SimplePrincipal(groupName),"/home/groups/test");
   
     Value value=adminSession.getValueFactory().createValue("Sample Group", PropertyType.STRING);
     group.setProperty("./profile/givenName", value);
   
     value=adminSession.getValueFactory().createValue("Test Group", PropertyType.STRING);
     group.setProperty("./profile/aboutMe", value);
   
     value=adminSession.getValueFactory().createValue("albin@gmail.com", PropertyType.STRING);
     group.setProperty("./profile/email", value);    
           
      }else{
     response.getWriter().write("Group already exist..");
      }
   
     if(userManager.getAuthorizable(userName)==null){
     User user=userManager.createUser(userName, password,new SimplePrincipal(userName),"/home/users/test");
     Value value=adminSession.getValueFactory().createValue("Issac", PropertyType.STRING);
     user.setProperty("./profile/familyName", value);
   
     value=adminSession.getValueFactory().createValue("Albin", PropertyType.STRING);
     user.setProperty("./profile/givenName", value);
   
     value=adminSession.getValueFactory().createValue("Test User", PropertyType.STRING);
     user.setProperty("./profile/aboutMe", value);
   
     value=adminSession.getValueFactory().createValue("albin@gmail.com", PropertyType.STRING);
     user.setProperty("./profile/email", value);    
   
      }else
      {
      response.getWriter().write("User already exist..");  
      }
   
   
     Group group = (Group)(userManager.getAuthorizable(groupName));
     group.addMember(userManager.getAuthorizable(userName));
                       
} catch (Exception e) {
e.printStackTrace();
response.getWriter().write("Not able to perform User Management.."+resolverFactory);
} finally {
      if (adminResolver != null) adminResolver.close();
           
}

}

protected final void doGet(final SlingHttpServletRequest request,
final SlingHttpServletResponse response) throws IOException {
doPost(request, response);
}


private static class SimplePrincipal implements Principal {
        protected final String name;

        public SimplePrincipal(String name) {
            if (StringUtils.isBlank(name)) {
                throw new IllegalArgumentException("Principal name cannot be blank.");
            }
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public int hashCode() {
            return name.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Principal) {
                return name.equals(((Principal) obj).getName());
            }
            return false;
        }
    }

}




Friday, April 3, 2015

How to create different renditions for the Image in Adobe CQ5?

While uploading the images to DAM, CQ5 will create renditions of an image that include different sizes of the same image.This can be helpful when we need to create thumbnails or smaller views of large, high-resolution images.



We can configure the DAM Update Asset workflow to create the different renditions.

  • Login to http://localhost:4502/etc/workflow/models/dam/update_asset.html
  • In the workflow model select the thumbnail creation step and edit, in the process tab of the step we can add custom rendition values.
  • Save the workflow




While uploading the images, the configured thumbnails will be created.




How to use HTML5 adaptive image in Adobe CQ5?

The srcset attribute in HTML5 <img> element, allows us to specify different images for varying viewport widths and pixel densities. This allows us to load a larger image for new high resolution devices while displaying lower resolution images for others

<img src="image-src.png" srcset="image-1x.png 1x, image-2x.png 2x,image-3x.png 3x, image-4x.png 4x">

The width also can be specified to select the images.

<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w" alt="Sample Image">

While uploading the images to DAM, CQ5 will create renditions of an image that include different sizes of the same image.This can be helpful when we need to create thumbnails or smaller views of large, high-resolution images.


The original or different rendition images can be used in HTML5 Adaptive image to display the images based on pixel density of the device,  browser will serve the image based on the resolution of the client.

<img src="/content/dam/Albin/Untitled.jpg/jcr:content/renditions/original" srcset="/content/dam/Albin/Untitled.jpg/jcr:content/renditions/cq5dam.thumbnail.319.319.png 1x,/content/dam/Albin/Untitled.jpg/jcr:content/renditions/original" alt="Sample Image">


Saturday, March 28, 2015

NullPointerException: currentDesign.getDoctype(currentStyle).toRequest(request);

We were getting the NullpoiterException while accessing the pages.

Caused by: java.lang.NullPointerException
at org.apache.jsp.apps.sample.design.components.pages.pageShell.pageShell_jsp._jspService(pageShell_jsp.java:227)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:502)
... 117 more

NullpointerException is thrown while getting the Doctype of the page design.

if (currentDesign != null) {
        currentDesign.getDoctype(currentStyle).toRequest(request);
    }

This issue was getting resolved after restarting the server.

After analysis the currentDesign  and currentStyle objects are not null and getDoctype method is throwing NullpoiterException.

The currentStyle  refers to the path (currentStyle.getPath())- /etc/designs/default.

By default /etc/designs/default/jcr:content path will not have cq:doctype property specified.

To resolve the issue we have added the  cq:doctype - html_5 property to /etc/designs/default/jcr:content

doctype_html5