io.jawg.osmcontributor.ui.adapters.parser.OpeningHoursValueParser.java Source code

Java tutorial

Introduction

Here is the source code for io.jawg.osmcontributor.ui.adapters.parser.OpeningHoursValueParser.java

Source

/**
 * Copyright (C) 2016 eBusiness Information
 *
 * This file is part of OSM Contributor.
 *
 * OSM Contributor is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * OSM Contributor is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with OSM Contributor.  If not, see <http://www.gnu.org/licenses/>.
 */
package io.jawg.osmcontributor.ui.adapters.parser;

import org.joda.time.LocalTime;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Singleton;

import io.jawg.osmcontributor.model.utils.OpeningHours;

/**
 * @author Tommy Buonomo on 18/07/16.
 */

@Singleton
public class OpeningHoursValueParser implements ValueParser<List<OpeningHours>> {
    public static final String NON_STOP = "24/7";
    public static final String RANGE_SEP = "-";
    public static final String RULE_SEP = ",";
    public static final String HOURS_SEP = ", ";
    public static final String DAYS_SEP = " ";

    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormat.forPattern("kk:mm");

    @Inject
    public OpeningHoursValueParser() {
    }

    @Override
    public String toValue(List<OpeningHours> openingHours) {
        StringBuilder openingHoursBuilder = new StringBuilder();

        for (OpeningHours o : openingHours) {
            openingHoursBuilder.append(openingHoursBuilder.length() == 0 ? "" : HOURS_SEP);
            openingHoursBuilder.append(toSingleValue(o));
        }

        return openingHoursBuilder.toString();
    }

    private StringBuilder toSingleValue(OpeningHours openingHours) {
        StringBuilder hoursBuilder = new StringBuilder();

        if (openingHours.getFromTime() == null && openingHours.getToTime() == null) {
            return new StringBuilder("");
        }

        // Return 24/7 if opening hours id non-stop
        if (isNonStop(openingHours)) {
            return new StringBuilder(NON_STOP);
        } else {
            OpeningHours.Days[] days = openingHours.getDays();
            StringBuilder daysBuilder = new StringBuilder();
            for (int i = 0; i < days.length; i++) {
                OpeningHours.Days d = days[i];

                // Get the period in days
                if (d != null) {
                    // A day is detected, look if this is a period by iterate the next days
                    String fromDay = d.getData();
                    String toDay = null;
                    i++;
                    while (i < days.length && days[i] != null) {
                        toDay = days[i].getData();
                        i++;
                    }

                    daysBuilder.append(daysBuilder.length() == 0 ? "" : RULE_SEP);
                    daysBuilder.append(fromDay);
                    if (toDay != null) {
                        // This is a period
                        daysBuilder.append(RANGE_SEP).append(toDay);
                    }
                }
            }
            hoursBuilder.append(daysBuilder);
            hoursBuilder.append(" ");
            hoursBuilder.append(TIME_FORMATTER.print(openingHours.getFromTime()));
            hoursBuilder.append(RANGE_SEP);
            hoursBuilder.append(TIME_FORMATTER.print(openingHours.getToTime()));
        }

        return hoursBuilder;
    }

    public boolean isNonStop(OpeningHours openingHours) {
        for (OpeningHours.Days b : openingHours.getDays()) {
            if (b == null) {
                return false;
            }
        }
        return isNonStopHours(openingHours);
    }

    public boolean isNonStopHours(OpeningHours openingHours) {
        if (openingHours.getFromTime().equals(openingHours.getToTime())) {
            return true;
        }

        LocalTime diff = openingHours.getToTime().minus(new Period(openingHours.getFromTime().getHourOfDay(),
                openingHours.getFromTime().getMinuteOfHour(), 0, 0));

        return diff.minus(new Period(23, 50, 0, 0)).getMinuteOfHour() < 10;
    }

    @Override
    public List<OpeningHours> fromValue(String value) {
        if (value.trim().isEmpty()) {
            return null;
        }

        List<OpeningHours> openingHoursList = new ArrayList<>();
        String[] openingHours = value.split(HOURS_SEP);

        for (String o : openingHours) {
            if (!o.trim().isEmpty()) {
                fromSingleValue(o, openingHoursList);
            }
        }

        return openingHoursList;
    }

    public void fromSingleValue(String value, List<OpeningHours> openingHoursList) {
        // TODO: 19/07/16 We,Fr-Sa 10:45-19:15, Tu,Sa-Su 05:30-17:30, We 08:00-18:00
        OpeningHours openingHours = new OpeningHours();
        openingHours.setAllDaysActivated(false);

        String[] openingHoursValues = value.split(DAYS_SEP);
        String daysPart = null;
        String hoursPart = null;

        if (value.equals("24/7")) {
            daysPart = "Mo-Su";
            hoursPart = "24:00-24:00";
        } else if (openingHoursValues.length == 2) {
            daysPart = openingHoursValues[0];
            hoursPart = openingHoursValues[1];
        } else if (openingHoursValues.length == 1) {
            hoursPart = openingHoursValues[0];
        }

        if (daysPart != null) {
            String[] dayPeriods = daysPart.split(RULE_SEP);
            for (String period : dayPeriods) {
                if (isPeriod(period)) {
                    OpeningHours.Days[] d = OpeningHours.Days.fromDatas(period.split(RANGE_SEP));
                    for (int i = d[0].ordinal(); i <= d[1].ordinal(); i++) {
                        openingHours.setDayActivated(i, true);
                    }
                } else {
                    openingHours.setDayActivated(OpeningHours.Days.fromData(period).ordinal(), true);
                }
            }
        }

        if (hoursPart != null) {
            String[] hours = hoursPart.split(",");
            if (hours.length > 1) {
                for (String hour : hours) {
                    value = daysPart + " " + hour;
                    fromSingleValue(value, openingHoursList);
                }
            } else {
                String[] hourPeriod = hoursPart.split(RANGE_SEP);
                LocalTime from = TIME_FORMATTER.parseLocalTime(hourPeriod[0]);
                if (hourPeriod.length > 1) {
                    LocalTime to = TIME_FORMATTER.parseLocalTime(hourPeriod[1]);
                    openingHours.setToTime(to);
                } else {
                    openingHours.setToTime(from.plusMinutes(5));
                }
                openingHours.setFromTime(from);
                openingHoursList.add(openingHours);
            }
        }
        //return openingHours;
    }

    @Override
    public int getPriority() {
        return ParserManager.PRIORITY_HIGH;
    }

    /**
     * Return true if the days expression is a period
     * For example 'Sa-Su' is a period, 'Tu' is not.
     * @param period
     * @return
     */
    private boolean isPeriod(String period) {
        return period.contains(RANGE_SEP);
    }

}