/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.myfaces.extensions.cdi.javaee.jsf.impl.view;
import org.apache.myfaces.extensions.cdi.core.api.view.definition.ViewDefinition;
import org.apache.myfaces.extensions.cdi.javaee.jsf.api.view.definition.JsfViewExtension;
import org.apache.myfaces.extensions.cdi.javaee.jsf.api.view.definition.NavigationMode;
import org.apache.myfaces.extensions.cdi.javaee.jsf.api.view.definition.Page;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
/**
* @author Gerhard Petracek
*/
@SuppressWarnings({"UnusedDeclaration"})
public class ViewDefinitionExtension implements Extension
{
public void processPageDefinitions(@Observes ProcessAnnotatedType processAnnotatedType)
{
if (processAnnotatedType.getAnnotatedType().isAnnotationPresent(Page.class))
{
addPageDefinition(processAnnotatedType.getAnnotatedType().getJavaClass());
processAnnotatedType.veto();
}
}
private void addPageDefinition(Class pageDefinitionClass)
{
if(!ViewDefinition.class.isAssignableFrom(pageDefinitionClass))
{
throw new IllegalArgumentException(
"the page definition " + pageDefinitionClass.getName() + " has to implement "
+ ViewDefinition.class.getName());
}
@SuppressWarnings({"unchecked"})
Class<? extends ViewDefinition> viewDefinitionClass = (Class<? extends ViewDefinition>)pageDefinitionClass;
if(Modifier.isAbstract(viewDefinitionClass.getModifiers()))
{
return;
}
Class<?> currentClass = viewDefinitionClass;
String rootPath = "/";
String basePath = rootPath;
String currentBasePath;
Map<String, String> simpleClassNameToPathMapping = new HashMap<String, String>();
String defaultPageName = "";
String pageName = defaultPageName;
String defaultExtension = JsfViewExtension.XHTML;
String extension = defaultExtension;
NavigationMode defaultNavigationMode = NavigationMode.FORWARD;
NavigationMode navigationMode = defaultNavigationMode;
//TODO
Page pageAnnotation;
while(!Object.class.getName().equals(currentClass.getName()))
{
if(currentClass.isAnnotationPresent(Page.class))
{
pageAnnotation = currentClass.getAnnotation(Page.class);
if(!pageAnnotation.extension().equals(defaultExtension))
{
extension = pageAnnotation.extension();
}
if(!pageAnnotation.basePath().equals(rootPath))
{
currentBasePath = pageAnnotation.basePath();
if(!".".equals(currentBasePath))
{
simpleClassNameToPathMapping.put(currentClass.getSimpleName(), currentBasePath);
}
if(rootPath.equals(basePath))
{
basePath = currentBasePath;
}
}
if(!pageAnnotation.navigation().equals(defaultNavigationMode))
{
navigationMode = pageAnnotation.navigation();
}
if(!pageAnnotation.name().equals(defaultPageName))
{
pageName = pageAnnotation.name();
}
}
currentClass = currentClass.getSuperclass();
}
StringBuilder viewId = new StringBuilder(basePath);
if(pageName.equals(""))
{
String className = viewDefinitionClass.getName();
//MyClass$MyInnerClass will be converted to /MyClass/MyInnerClass
if(className.contains("$") && ".".equals(basePath))
{
basePath = "";
className = className.substring(className.lastIndexOf(".") + 1);
className = convertToPathSyntax(className, simpleClassNameToPathMapping);
}
else if(className.contains("$"))
{
className = className.substring(className.lastIndexOf("$") + 1);
}
else
{
className = className.substring(className.lastIndexOf(".") + 1);
}
className = className.substring(0, 1).toLowerCase() + className.substring(1);
viewId.append(className);
}
else
{
viewId.append(pageName);
}
viewId.append(".");
viewId.append(extension);
String result = viewId.toString();
if(result.startsWith("."))
{
if(result.startsWith("./"))
{
result = result.substring(1);
}
else
{
result = rootPath + result.substring(1);
}
}
ViewDefinitionCache.addViewDefinition(
result, new ViewDefinitionEntry(result, viewDefinitionClass, navigationMode));
}
private String convertToPathSyntax(String className, Map<String, String> simpleClassNameToPathMapping)
{
String[] parts = className.split("\\$");
StringBuilder path = new StringBuilder();
for(String part : parts)
{
if(simpleClassNameToPathMapping.containsKey(part))
{
path.append(simpleClassNameToPathMapping.get(part));
}
else
{
path.append(part.substring(0, 1).toLowerCase());
path.append(part.substring(1));
}
path.append("/");
}
String result = path.toString();
return result.substring(0, result.length() - 1);
}
}