com.omnigon.aem.handlebars.helpers.MomentHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.omnigon.aem.handlebars.helpers.MomentHelper.java

Source

/*
 * Copyright (c) 2016 Omnigon Communications, LLC. All rights reserved.
 *
 * This software is the confidential and proprietary information of Omnigon Communications, LLC
 * ("Confidential Information"). You shall not disclose such Confidential Information and shall access and use it only
 * in accordance with the terms of the license agreement you entered into with Omnigon Communications, LLC, its
 * subsidiaries, affiliates or authorized licensee. Unless required by applicable law or agreed to in writing, this
 * Confidential Information is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the license agreement for the specific language governing permissions and limitations.
 */

package com.omnigon.aem.handlebars.helpers;

import com.github.jknack.handlebars.Options;
import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * This Handlebars' Helper class formats the given datetime moment with provided format:
 * <p>
 * Examples:
 * <p>
 * {{moment '2016-10-17T17:11:12Z'}}, expected 2016-10-17
 * {{moment '2016-10-17T17:11:12Z' 'DD MMM'}} expected 17 Oct
 * {{moment '2016-10-17T17:11:12Z' format='DD MMM YYYY'}}, expected 17 Oct 2016
 * {{moment format='DD MMM YYYY HH:mm:ss'}}, expected [Current date and time], e.g. 17 Oct 2016 23:02:45
 * <p>
 * Moment shall be encoded with ISO8601 format or its subset.
 * <p>
 * TODO: write a unit test, ZonedDateTime.now needs to be mocked properly
 */
@Service
@Component
public class MomentHelper implements HandlebarsHelper {

    private static Logger logger = LoggerFactory.getLogger(MomentHelper.class);
    public static final String NAME = "moment";

    private static final String DEFAULT_FORMAT = "YYYY-MM-dd";
    private static final String FORMAT_PARAM = "format";

    @Override
    public String getName() {
        return NAME;
    }

    @Override
    public CharSequence apply(Object context, Options options) throws IOException {

        Date date = null;
        if (context instanceof Date) {
            date = (Date) context;
        } else {
            try {
                date = new Date((Long) context); //date gets converted to Long for handlebars, need to handle.
            } catch (Exception e) {
                logger.error("Invalid object passed as date, cannot cast to string or string is not an integer");
                return StringUtils.EMPTY;
            }

        }

        String format = DEFAULT_FORMAT; // default parameter
        if (options.params.length > 0) {
            format = options.params[0].toString();
        } else if (options.hash.containsKey(FORMAT_PARAM)) {
            format = options.hash.get(FORMAT_PARAM).toString();
        }

        /* Moment.js and Java Datetime format patterns differ in some details.
           Moment.js:
        D DD 1..31 Day of month
        DDD DDDD 1..365 Day of year
        ddd dddd Mon...Sunday Day name in locale set by moment.locale()
            
           Java:
        D DDD Day in year Number 189
        d dd Day in month Number 10
            
        So we need to convert D to d and DD to dd.
        */
        if (!format.contains("DDD") // true for DDDD as well
                && format.contains("D")) { // true for DD as well
            format = format.replace("D", "d");
        }

        String formattedMoment = format(format, date);

        return formattedMoment;
    }

    public static String format(String pattern, Date date) {
        if (StringUtils.isBlank(pattern) || date == null) {
            return StringUtils.EMPTY;
        }
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(date);
    }

}