/* * Copyright 2011 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a> * * 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.ocpsoft.rewrite.el; import java.util.Iterator; import org.ocpsoft.common.services.ServiceLoader; import org.ocpsoft.logging.Logger; import org.ocpsoft.rewrite.el.spi.BeanNameResolver; /** * This implementation of {@link Expression} is able to automatically build the EL expression from the type of the bean. * * @author Christian Kaltepoth */ class TypeBasedExpression implements Expression { private static Logger log = Logger.getLogger(TypeBasedExpression.class); private final Class<?> clazz; private final String component; private String cachedExpression; /** * Standard way to create a {@link TypeBasedExpression}. The constructor requires the caller to supply the type of * the bean and the component, which may be a field or method name. */ public TypeBasedExpression(Class<?> clazz, String component) { this.clazz = clazz; this.component = component; } @Override public String getExpression() { // lazily perform the lookup and cache the result if (cachedExpression == null) { cachedExpression = lookupBeanName(); } return cachedExpression; } @SuppressWarnings("unchecked") private String lookupBeanName() { // load the available SPI implementations Iterator<BeanNameResolver> iterator = ServiceLoader.load(BeanNameResolver.class).iterator(); while (iterator.hasNext()) { BeanNameResolver resolver = iterator.next(); // check if this implementation is able to tell the name String beanName = resolver.getBeanName(clazz); if (log.isTraceEnabled()) { log.trace("Service provider [{}] returned [{}] for class [{}]", new Object[] { resolver.getClass().getSimpleName(), beanName, clazz.getName() }); } // the first result is accepted if (beanName != null) { // create the complete EL expression including the component String el = new StringBuilder() .append(beanName).append('.').append(component) .toString(); if (log.isTraceEnabled()) { log.debug("Creation of EL expression for component [{}] of class [{}] successful: {}", new Object[] { component, clazz.getName(), el }); } return el; } } throw new IllegalStateException("Unable to obtain EL name for bean of type [" + clazz.getName() + "] from any of the SPI implementations. You should conside placing a @" + ELBeanName.class.getSimpleName() + " on the class."); } @Override public String toString() { return getExpression(); } }