001// Copyright 2009 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.internal.services; 016 017import java.util.Set; 018 019import org.apache.tapestry5.SymbolConstants; 020import org.apache.tapestry5.internal.services.ComponentDependencyRegistry.DependencyType; 021import org.apache.tapestry5.ioc.annotations.Symbol; 022import org.apache.tapestry5.model.ComponentModel; 023import org.apache.tapestry5.services.ComponentClassResolver; 024 025public class ComponentModelSourceImpl implements ComponentModelSource 026{ 027 private final ComponentClassResolver resolver; 028 029 private final ComponentInstantiatorSource source; 030 031 private final ComponentDependencyRegistry componentDependencyRegistry; 032 033 private final PageSource pageSource; 034 035 private final boolean multipleClassLoaders; 036 037 public ComponentModelSourceImpl(ComponentClassResolver resolver, ComponentInstantiatorSource source, 038 ComponentDependencyRegistry componentDependencyRegistry, 039 PageSource pageSource, 040 @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode, 041 @Symbol(SymbolConstants.MULTIPLE_CLASSLOADERS) boolean multipleClassLoaders) 042 { 043 this.resolver = resolver; 044 this.source = source; 045 this.componentDependencyRegistry = componentDependencyRegistry; 046 this.pageSource = pageSource; 047 this.multipleClassLoaders = !productionMode && multipleClassLoaders; 048 } 049 050 public ComponentModel getModel(String componentClassName) 051 { 052 if (multipleClassLoaders && isPage(componentClassName)) 053 { 054 055 final Set<String> superclasses = componentDependencyRegistry.getDependencies( 056 componentClassName, DependencyType.SUPERCLASS); 057 058 if (!superclasses.isEmpty()) 059 { 060 final String superclass = superclasses.iterator().next(); 061 if (isPage(superclass)) 062 { 063 getModel(superclass); 064 try 065 { 066 pageSource.getPage(resolver.getLogicalName(componentClassName)); 067 } 068 catch (IllegalStateException e) 069 { 070 // This can be thrown in PageSourceImpl in case an 071 // infinite method call recursion is detected. In 072 // that case, the page instance is already created, 073 // so the objective of the line above is already 074 // fulfilled and we can safely ignore the exception 075 } 076 } 077 } 078 } 079 return source.getInstantiator(componentClassName).getModel(); 080 } 081 082 public ComponentModel getPageModel(String pageName) 083 { 084 return getModel(resolver.resolvePageNameToClassName(pageName)); 085 } 086 087 private boolean isPage(String componentClassName) 088 { 089 return componentClassName.contains(".pages."); 090 } 091}