001 // Copyright 2006, 2007, 2008, 2009, 2010, 2011 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 015 package org.apache.tapestry5.internal.services; 016 017 import org.apache.tapestry5.Binding; 018 import org.apache.tapestry5.ComponentResources; 019 import org.apache.tapestry5.ioc.Location; 020 import org.apache.tapestry5.ioc.internal.util.InternalUtils; 021 import org.apache.tapestry5.ioc.internal.util.TapestryException; 022 import org.apache.tapestry5.services.BindingFactory; 023 import org.apache.tapestry5.services.BindingSource; 024 025 import java.util.Map; 026 027 public class BindingSourceImpl implements BindingSource 028 { 029 private final Map<String, BindingFactory> factories; 030 031 private final StringInterner interner; 032 033 public BindingSourceImpl(Map<String, BindingFactory> factories, StringInterner interner) 034 { 035 this.factories = factories; 036 this.interner = interner; 037 } 038 039 public Binding newBinding(String description, ComponentResources container, String defaultPrefix, String expression) 040 { 041 return newBinding(description, container, container, defaultPrefix, expression, null); 042 } 043 044 public Binding newBinding(String description, ComponentResources container, ComponentResources component, 045 String defaultPrefix, String expression, Location location) 046 { 047 assert InternalUtils.isNonBlank(description); 048 assert container != null; 049 assert InternalUtils.isNonBlank(defaultPrefix); 050 assert component != null; 051 052 // TAP5-845: The expression may be the empty string. This is ok, if it's compatible with 053 // the default prefix (the empty string is not a valid property expression, but is valid 054 // as a literal string, perhaps as an informal parameter). 055 056 // Location might be null 057 058 String subexpression = expression; 059 int colonx = expression.indexOf(':'); 060 061 BindingFactory factory = null; 062 063 if (colonx > 0) 064 { 065 String prefix = expression.substring(0, colonx); 066 067 factory = factories.get(prefix); 068 if (factory != null) 069 subexpression = expression.substring(colonx + 1); 070 } 071 072 if (factory == null) 073 factory = factories.get(defaultPrefix); 074 075 // And if that's null, what then? We assume that the default prefix is a valid prefix, 076 // or we'll get an NPE below and report it like any other error. 077 078 try 079 { 080 return factory.newBinding(interner.intern(description), container, component, subexpression, location); 081 } catch (Exception ex) 082 { 083 throw new TapestryException(String.format("Could not convert '%s' into a component parameter binding: %s", expression, InternalUtils.toMessage(ex)), location, ex); 084 } 085 } 086 }