All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.liferay.poshi.runner.elements.PoshiNodeFactory Maven / Gradle / Ivy

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library 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 Lesser General Public License for more
 * details.
 */

package com.liferay.poshi.runner.elements;

import com.google.common.reflect.ClassPath;

import com.liferay.poshi.runner.script.PoshiScriptParserException;
import com.liferay.poshi.runner.script.UnbalancedCodeException;
import com.liferay.poshi.runner.util.Dom4JUtil;
import com.liferay.poshi.runner.util.FileUtil;

import java.io.IOException;

import java.lang.reflect.Modifier;

import java.net.URL;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.dom4j.Comment;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;

/**
 * @author Kenji Heigel
 */
public abstract class PoshiNodeFactory {

	public static PoshiNode newPoshiNode(Node node) {
		PoshiNode newPoshiNode = null;

		if (node instanceof Comment) {
			newPoshiNode = _newPoshiComment((Comment)node);
		}

		if (node instanceof Element) {
			newPoshiNode = _newPoshiElement((Element)node);
		}

		if (newPoshiNode != null) {
			return newPoshiNode;
		}

		String nodeContent;

		try {
			nodeContent = Dom4JUtil.format(node);
		}
		catch (IOException ioException) {
			nodeContent = node.toString();
		}

		throw new RuntimeException("Unknown node\n" + nodeContent);
	}

	public static PoshiNode newPoshiNode(
			PoshiNode parentPoshiNode, String poshiScript)
		throws PoshiScriptParserException {

		PoshiNode newPoshiNode = null;

		newPoshiNode = _newPoshiComment(poshiScript);

		if (newPoshiNode != null) {
			return newPoshiNode;
		}

		newPoshiNode = _newPoshiElement(
			(PoshiElement)parentPoshiNode, poshiScript);

		if (newPoshiNode != null) {
			return newPoshiNode;
		}

		throw new PoshiScriptParserException(
			"Invalid Poshi Script syntax", poshiScript, parentPoshiNode);
	}

	public static PoshiNode newPoshiNode(String content, URL url)
		throws PoshiScriptParserException {

		try {
			content = content.trim();

			if (content.startsWith(" newPoshiNodeFromFile(URL url)
		throws PoshiScriptParserException {

		try {
			String content = FileUtil.read(url);

			return newPoshiNode(content, url);
		}
		catch (IOException ioException) {
			throw new RuntimeException(
				"Unable to read file: " + url.getFile(),
				ioException.getCause());
		}
	}

	protected static final Set validationInitialized =
		Collections.synchronizedSet(new HashSet<>());

	private static DefinitionPoshiElement _getDefinitionPoshiElement() {
		for (PoshiElement poshiElement : _poshiElements) {
			if (poshiElement instanceof DefinitionPoshiElement) {
				return (DefinitionPoshiElement)poshiElement;
			}
		}

		return new DefinitionPoshiElement();
	}

	private static PoshiComment _newPoshiComment(Comment comment) {
		for (PoshiComment poshiComment : _poshiComments) {
			PoshiComment newPoshiComment = poshiComment.clone(comment);

			if (newPoshiComment != null) {
				return newPoshiComment;
			}
		}

		return null;
	}

	private static PoshiComment _newPoshiComment(String poshiScript)
		throws PoshiScriptParserException {

		for (PoshiComment poshiComment : _poshiComments) {
			PoshiComment newPoshiComment = poshiComment.clone(poshiScript);

			if (newPoshiComment != null) {
				return newPoshiComment;
			}
		}

		return null;
	}

	private static PoshiElement _newPoshiElement(Element element) {
		for (PoshiElement poshiElement : _poshiElements) {
			PoshiElement newPoshiElement = poshiElement.clone(element);

			if (newPoshiElement != null) {
				return newPoshiElement;
			}
		}

		return null;
	}

	private static PoshiElement _newPoshiElement(
			PoshiElement parentPoshiElement, String poshiScript)
		throws PoshiScriptParserException {

		for (PoshiElement poshiElement : _poshiElements) {
			PoshiElement newPoshiElement = poshiElement.clone(
				parentPoshiElement, poshiScript);

			if (newPoshiElement != null) {
				return newPoshiElement;
			}
		}

		return null;
	}

	private static final DefinitionPoshiElement _definitionPoshiElement;
	private static final List _poshiComments = new ArrayList<>();
	private static final List _poshiElements = new ArrayList<>();

	static {
		try {
			ClassPath classPath = ClassPath.from(
				PoshiNode.class.getClassLoader());

			List> poshiElementClasses = new ArrayList<>();

			for (ClassPath.ClassInfo classInfo :
					classPath.getTopLevelClasses(
						"com.liferay.poshi.runner.elements")) {

				poshiElementClasses.add(classInfo.load());
			}

			Collections.sort(
				poshiElementClasses,
				new Comparator>() {

					@Override
					public int compare(Class class1, Class class2) {
						String className1 = class1.getName();
						String className2 = class2.getName();

						return className1.compareTo(className2);
					}

				});

			for (Class clazz : poshiElementClasses) {
				if (Modifier.isAbstract(clazz.getModifiers()) ||
					!(PoshiComment.class.isAssignableFrom(clazz) ||
					  PoshiElement.class.isAssignableFrom(clazz))) {

					continue;
				}

				PoshiNode poshiNode =
					(PoshiNode)clazz.newInstance();

				if (poshiNode instanceof PoshiComment) {
					_poshiComments.add((PoshiComment)poshiNode);

					continue;
				}

				if (poshiNode instanceof PoshiElement) {
					_poshiElements.add((PoshiElement)poshiNode);
				}
			}

			_definitionPoshiElement = _getDefinitionPoshiElement();
		}
		catch (IllegalAccessException | InstantiationException | IOException
					exception) {

			throw new RuntimeException(exception);
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy