package com.cedricziel.idea.typo3.psi.visitor;
import com.cedricziel.idea.typo3.container.RouteProvider;
import com.cedricziel.idea.typo3.domain.TYPO3RouteDefinition;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiRecursiveElementVisitor;
import com.jetbrains.php.lang.psi.elements.ArrayCreationExpression;
import com.jetbrains.php.lang.psi.elements.ArrayHashElement;
import com.jetbrains.php.lang.psi.elements.PhpPsiElement;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Walks a psiFile recursively and parses the service definitions.
*/
public class RouteDefinitionParserVisitor extends PsiRecursiveElementVisitor {
private final String type;
private Map<String, List<TYPO3RouteDefinition>> routes;
private Map<String, List<TYPO3RouteDefinition>> ajaxRoutes;
public RouteDefinitionParserVisitor(Map<String, List<TYPO3RouteDefinition>> routes, Map<String, List<TYPO3RouteDefinition>> ajaxRoutes, String type) {
this.routes = routes;
this.ajaxRoutes = ajaxRoutes;
this.type = type;
}
@Override
public void visitElement(PsiElement element) {
if ((element instanceof ArrayCreationExpression)) {
ArrayCreationExpression arrayCreationExpression = (ArrayCreationExpression) element;
visitRouteCreation(arrayCreationExpression);
}
super.visitElement(element);
}
/**
* The following element structure should be parsed:
* <pre>
* return [
* // Login screen of the TYPO3 Backend
* 'login' => [
* 'path' => '/login',
* 'access' => 'public',
* 'target' => Controller\LoginController::class . '::formAction'
* ],
* ]
* </pre>
*
* @param element
*/
private void visitRouteCreation(ArrayCreationExpression element) {
Map<String, List<TYPO3RouteDefinition>> routeSet;
if (type.equals(RouteProvider.ROUTE_TYPE_BACKEND)) {
routeSet = this.routes;
} else {
routeSet = this.ajaxRoutes;
}
TYPO3RouteDefinition routeDefinition = new TYPO3RouteDefinition();
for (ArrayHashElement arrayHashElement : element.getHashElements()) {
PhpPsiElement child = arrayHashElement.getKey();
if (child instanceof StringLiteralExpression) {
String key = ((StringLiteralExpression) child).getContents();
PhpPsiElement valueMap = arrayHashElement.getValue();
if (valueMap == null) {
continue;
}
if (valueMap instanceof ArrayCreationExpression) {
ArrayCreationExpression propertyArray = (ArrayCreationExpression) valueMap;
routeDefinition.setName(key);
routeDefinition.setType(type);
routeDefinition.setElement(valueMap);
for (ArrayHashElement routePropertyHashElement : propertyArray.getHashElements()) {
String propertyName = ((StringLiteralExpression) routePropertyHashElement.getKey()).getContents();
if ("path".equals(propertyName)) {
routeDefinition.setPath(((StringLiteralExpression) routePropertyHashElement.getValue()).getContents());
}
if ("access".equals(propertyName)) {
routeDefinition.setPath(((StringLiteralExpression) routePropertyHashElement.getValue()).getContents());
}
}
if (!routeSet.containsKey(key)) {
routeSet.put(key, new ArrayList<>());
}
routeSet.get(key).add(routeDefinition);
}
}
}
}
}