Saturday, 21 April 2018

aemsync tool

AEM sync tool pushed code to multiple AEM instances instantly when there is a file change.

Prerequisites:

Install npm on your machine.

Installation

Run below npm command to install aemsync

npm install aemsync -g
The tool pushes code changes to AEM instance(s) upon a file change.
  • There is no vault dependency.
  • It can push to multiple instances at the same time (e.g. author and publish).
  • IDE/editor agnostic.
  • Works on Windows, Linux and Mac.

Wednesday, 14 March 2018

String encoding issue

Sometimes we may get a scenario where string need to be decoded. We may get request in correct format, but we need to make sure its correctly decoded.

package com.kishore.encode;

import java.nio.charset.StandardCharsets;

public class CharsetEncoding {
    public static void main(String[] args) {
        String name = "(Kishore PROĆ¢„¢)";
        byte[] bytes = name.getBytes(StandardCharsets.ISO_8859_1);
        name = new String(bytes, StandardCharsets.UTF_8);
        System.out.println("name ::" + name);
    }
}

Output: Kishore PRO™

Sunday, 18 February 2018

Ajax reqeuts getting cached in IE and Firefox

Usecase: Debug ajax cache issues in IE and Firefox.

Issue: Ajax requests return wrong or same data in IE and Firefox, since the requests get cached in the browser. Requests work for the first time, from next time browser will give the same result.

Root Cause: When a GET request is made to a web service, IE will automatically cache the responses from GET requests. Once IE has successfully made a GET request, it will no longer make a new AJAX call until the cache expires on that object.

Solutions:

  1. Use POST: Use POST requests instead of GET requests in your application. However, this is bad practise, simply because POST requests should only be used when you are submitting data or modifying a resource on the server.
  2. Response Headers: You can prevent caching by sending additional headers along with your response. By specifying the “Cache-Control” header with a value of “no-cache,no-store” and returning it with the web service response you can instruct the browser not to cache the result. For example in C#:HttpContext.Current.Response.AddHeader("Cache-Control","no-cache,no-store");
  3. Cache Buster: A cache-buster is a dynamic parameter that you append to a request which makes each request unique, most commonly a random number or the current date/time ticks.
    1. var url = '/get/userDetails?buster='+new Date().getTime();
  4. Disable Cache for JQuery AJAX Request:  If you’re using JQuery to perform your Ajax requests, you can add cache: false to the parameter list like so:
$.ajax({
    url: url,
    cache: false,
    dataType: 'json',
    type: "GET",
    data: data,
    success: func,
    error: ajaxError
});
If you want to globally setup cache for all JQuery AJAX requests use below code.
$.ajaxSetup({ cache: false });

Saturday, 4 November 2017

Get properties in AEM sling servlet

Usecase: I had a situation to fetch properties from node/page/cloud configurations from sling servlet. 

Issue: In wcmusepojo we can get these cloud configuarations using getInheritedPageProperties(). But inheritedPageProperties variable is not accessible in osgi service or sling servlet.

Solution:
To get properties of a node/page/cloud configurations from sling servlet do the following.
Below is sample servlet code.
/**
* Author: Kishore Polsani
*/
@Component(name = "com.kishore.aem.GetProperties", label = "Get Properties", immediate = true, metatype = true)
@Service
@Properties({ @Property(name = "service.description", value = "Get Properties"),
            @Property(name = "sling.servlet.paths", value = "/services/aemquickstart/getproperties", propertyPrivate = true),
            @Property(name = "service.vendor", value = "AEMQuickstart")
         })
    public class GetProperties extends SlingAllMethodsServlet implements Serializable {
        private static final long serialVersionUID = 1L;
        private Logger log = LoggerFactory.getLogger(GetProperties.class);
        
        @Reference
        protected SlingRepository repository;
        @Reference
        private ResourceResolverFactory resolverFactory;
        
        @Override
        protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException
                    {
                  
            try {
                Map<String, Object> param = new HashMap<String, Object>();  
                param.put(ResourceResolverFactory.SUBSERVICE, "readService");
                ResourceResolver resourceResolver=null;
                resourceResolver = resolverFactory.getServiceResourceResolver(param);
                /* Get this path from ajax call request*/
                Resource pageResource = resourceResolver.getResource("/etc/cloudservices/salesforce/kishore/jcr:content");
                Node configNode = pageResource.adaptTo(Node.class);
                configNode.getProperty("accesstoken");
                log.info("Access token from cloud config"+configNode.getProperty("accesstoken"));
                Session session = resourceResolver.adaptTo(Session.class);
                session.save();
            } catch (AccessDeniedException e) {
                log.error(e.getMessage());
            } catch (PathNotFoundException e) {
                log.error(e.getMessage());
            } catch (ItemExistsException e) {
                log.error(e.getMessage());
            } catch (ReferentialIntegrityException e) {
                log.error(e.getMessage());
            } catch (ConstraintViolationException e) {
                log.error(e.getMessage());
            } catch (InvalidItemStateException e) {
                log.error(e.getMessage());
            } catch (VersionException e) {
                log.error(e.getMessage());
            } catch (LockException e) {
                log.error(e.getMessage());
            } catch (NoSuchNodeTypeException e) {
                log.error(e.getMessage());
            } catch (LoginException e) {
                log.error(e.getMessage());
            } catch (RepositoryException e) {
                log.error(e.getMessage());
            }
        }   
}

Check this post to get properties in different way: Registering a Servlet for every Page in AEM

Monday, 11 September 2017

Creating RTE in Multifield

Discusses how to develop an AEM HTML Template Language (HTL - formerly known as Sightly) component that uses the WCMUsePojo class and uses a Multifield (granite/ui/components/foundation/form/multifield) in the component dialog. This article also covers using the Experience Manager Uber 6.3 JAR.
HTL is the AEM template language that can be used to replace use of JSP when developing an AEM component. HTL helps you to separate your design from your application logic. For more information, see Introduction to the HTML Template Language.