CreateContentListener.java

/*
 * Copyright 2017 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.genesys.server.component.listener;

import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map.Entry;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.genesys.server.exception.NotFoundElement;
import org.genesys.server.model.impl.Article;
import org.genesys.server.model.impl.MenuItem;
import org.genesys.server.service.ArticleService;
import org.genesys.server.service.MenuItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;

/**
 * This startup listener enumerates the resources in "default-content" directory
 * of this package. Each resource name represents a content slug (URL) of a
 * global content article and the contents is a JSON map of languages with
 * {"title":"..", "body":".."} values.
 *
 * <pre>
 * {
 * 	"en": {
 * 		"title": "Your user account is created",
 * 		"body": "The user account is now registered. You may use it to log in."
 * 	}, "sl": {
 * 	...
 *  }
 * }
 * </pre>
 *
 * @author mobreza
 */
@Component
public class CreateContentListener extends RunAsAdminListener {

	@Value("${auto.createContent}")
	// Must **not** be final!
	private boolean createContent;

	@Autowired
	private MenuItemService menuItemService;
	
	@Autowired
	private ArticleService articleService;

	@Override
	public void init() throws Exception {
		createArticles();
		createMenus();
	}

	private void createArticles() throws IOException, JsonProcessingException {
//		if (!createContent) {
//			LOG.warn("Skipping content creation on startup.");
//			return;
//		}

		LOG.info("Checking if default content exists");
		final ClassLoader classLoader = CreateContentListener.class.getClassLoader();
		final PathMatchingResourcePatternResolver rpr = new PathMatchingResourcePatternResolver(classLoader);
		final String resourcePath = "/default-content/*";
		final Resource[] rs = rpr.getResources(resourcePath);
		for (final Resource r : rs) {
			final String slug = r.getFilename().substring(0, r.getFilename().lastIndexOf(".json"));
			LOG.info("Using {} for article slug={}", r.getFilename(), slug);

			final ObjectMapper mapper = new ObjectMapper();
			try (InputStream stream = r.getInputStream()) {
				final JsonNode json = mapper.readTree(stream);
				
				JsonNode templateNode = json.get("template");
				final boolean isTemplate = templateNode != null && templateNode.booleanValue();

				final Iterator<Entry<String, JsonNode>> it = json.fields();
				while (it.hasNext()) {
					final Entry<String, JsonNode> entry = it.next();
					
					if (entry.getKey().length() != 2) {
						// Skip over non-language fields
						continue;
					}
					final Locale locale = new Locale(entry.getKey());

					try {
						// Load from default locale if exists
						articleService.getGlobalArticle(slug, locale);
					} catch (NotFoundElement e) {
						// If nothing is found, parse the resource and create content
						Article article = new Article();
						article.setSlug(slug);
						article.setOriginalLanguageTag(locale.toLanguageTag());
						article.setTitle(entry.getValue().get("title").asText());
						article.setBody(entry.getValue().get("body").asText());
						article.setTemplate(isTemplate);
						article.setPublishDate(Instant.now());
						articleService.createFast(article);
						LOG.warn("Created article for slug: {} lang={}", slug, locale.toLanguageTag());
					}
				}
			} catch (JsonParseException e) {
				LOG.error("Could not create global article {} from {}. JSON is not valid.", slug, r.getFilename());
			}
		}
	}

	/**
	 * Generates CMS Menu and MenuItems
	 */
	private void createMenus() {
		LOG.info("Checking if default menus exist");

		var languageTag = Locale.ENGLISH.getLanguage();
		
		// legal
		menuItemService.ensureMenuItem("legal", new MenuItem("/content/legal/disclaimer", "menu.disclaimer", languageTag));
		menuItemService.ensureMenuItem("legal", new MenuItem("/content/legal/terms", "menu.terms", languageTag));
		menuItemService.ensureMenuItem("legal", new MenuItem("/content/legal/copying", "menu.copying", languageTag));
		menuItemService.ensureMenuItem("legal", new MenuItem("/content/legal/privacy", "menu.privacy", languageTag));

		// about
		menuItemService.ensureMenuItem("about", new MenuItem("/content/about/about", "menu.about", languageTag));
		menuItemService.ensureMenuItem("about", new MenuItem("/content/about/contact", "menu.contact", languageTag));
		menuItemService.ensureMenuItem("about", new MenuItem("/content/about/what-is-genesys", "menu.what-is-genesys", languageTag));
		menuItemService.ensureMenuItem("about", new MenuItem("/content/about/history-of-genesys", "menu.history-of-genesys", languageTag));
		menuItemService.ensureMenuItem("about", new MenuItem("/content/about/newsletter", "menu.newsletter", languageTag));
		menuItemService.ensureMenuItem("about", new MenuItem("/content/about/frequently-asked-questions", "menu.faq", languageTag));
		menuItemService.ensureMenuItem("about", new MenuItem("/content/help/how-to-use-genesys", "menu.how-to-use-genesys", languageTag));

		// legal
		menuItemService.ensureMenuItem("help", new MenuItem("/content/help/how-to-use-genesys", "menu.how-to-use-genesys", languageTag));
		// contentService.ensureMenuItem("help", "/content/help/about-genesys-data",
		// "menu.about-genesys-data");
		// contentService.ensureMenuItem("help", "/content/help/who-uses-genesys",
		// "menu.who-uses-genesys");
		// contentService.ensureMenuItem("help", "/content/help/how-to-use-genesys",
		// "menu.how-to-use-genesys");
		menuItemService.ensureMenuItem("help", new MenuItem("/content/about/about", "menu.about", languageTag));

	}
}