LocaleURLMatcher.java

/*
 * Copyright 2020 Global Crop Diversity Trust
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gringlobal.spring.locale;

import lombok.extern.slf4j.Slf4j;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



/**
 * The Class LocaleURLMatcher.
 */
@Slf4j
public class LocaleURLMatcher {
	private static final Pattern localePattern = Pattern.compile("^/([a-z]{2}(?:\\-[a-z]{2})?)(/.*)");
	private String[] excludedPaths;

	public void setExcludedPaths(String[] excludedPaths) {
		this.excludedPaths = excludedPaths;
	}

	public boolean isExcludedPath(String url) {
		for (String excludedPath : excludedPaths) {
			if (url.startsWith(excludedPath)) {
				if (log.isDebugEnabled()) {
					log.debug("Excluded: {} matches {}", excludedPath, url);
				}
				return true;
			}
		}

		return false;
	}

	public boolean isExcluded(String url) {
		for (String excludedPath : excludedPaths) {
			if (url.startsWith(excludedPath)) {
				if (log.isDebugEnabled()) {
					log.debug("Excluded: {} matches {}", excludedPath, url);
				}
				return true;
			}
		}

		if (fastCheck(url)) {
			return true;
		}

		return false;
	}

	private boolean fastCheck(String url) {
		char[] dst = new char[7];
		url.getChars(0, Math.min(url.length(), 7), dst, 0);
		
		// Check language
		if (dst[0] != '/')
			return false;
		if (dst[1] < 'a' || dst[1] > 'z')
			return false;
		if (dst[2] < 'a' || dst[2] > 'z')
			return false;

		// end processing
		if (dst[3] == '/')
			return true;

		// Check country
		if (dst[3] != '-')
			return false;
		if (dst[4] < 'a' || dst[4] > 'z')
			return false;
		if (dst[5] < 'a' || dst[5] > 'z')
			return false;

		if (dst[6] != '/')
			return false;

		return true;
	}

	public Matcher matcher(String url) {
		return localePattern.matcher(url);
	}

}