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 015package org.apache.tapestry5.internal.services; 016 017import org.apache.tapestry5.Binding; 018import org.apache.tapestry5.ComponentResources; 019import org.apache.tapestry5.ioc.Location; 020import org.apache.tapestry5.ioc.internal.util.InternalUtils; 021import org.apache.tapestry5.ioc.internal.util.TapestryException; 022import org.apache.tapestry5.services.BindingFactory; 023import org.apache.tapestry5.services.BindingSource; 024 025import java.util.Map; 026 027public 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}