001 // Copyright 2004, 2005 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.tapestry.binding; 016 017 import org.apache.hivemind.Location; 018 import org.apache.hivemind.util.Defense; 019 import org.apache.tapestry.BindingException; 020 import org.apache.tapestry.IBinding; 021 import org.apache.tapestry.coerce.ValueConverter; 022 023 /** 024 * Base class for {@link IBinding}implementations. 025 * 026 * @author Howard Lewis Ship 027 */ 028 029 public abstract class AbstractBinding implements IBinding 030 { 031 /** @since 4.0 */ 032 033 protected final String _description; 034 035 /** @since 4.0 */ 036 037 private final ValueConverter _valueConverter; 038 039 /** @since 3.0 */ 040 041 private final Location _location; 042 043 /** @since 3.0 */ 044 045 protected AbstractBinding(String description, ValueConverter valueConverter, Location location) 046 { 047 Defense.notNull(description, "description"); 048 Defense.notNull(valueConverter, "valueConverter"); 049 050 _description = description; 051 _valueConverter = valueConverter; 052 _location = location; 053 } 054 055 public Location getLocation() 056 { 057 return _location; 058 } 059 060 /** 061 * Overridden in subclasses that are not invariant. 062 */ 063 064 public void setObject(Object value) 065 { 066 throw createReadOnlyBindingException(this); 067 } 068 069 /** 070 * Default implementation: returns true. 071 * 072 * @since 2.0.3 073 */ 074 075 public boolean isInvariant() 076 { 077 return true; 078 } 079 080 public Object getObject(Class type) 081 { 082 Defense.notNull(type, "type"); 083 084 Object raw = getObject(); 085 086 try 087 { 088 return _valueConverter.coerceValue(raw, type); 089 } 090 catch (Exception ex) 091 { 092 String message = BindingMessages.convertObjectError(this, ex); 093 094 throw new BindingException(message, getComponent(), _location, this, ex); 095 } 096 } 097 098 /** 099 * Returns the component to which this binding is connected; this is currently only used when 100 * building certain exceptions. This implementation returns null. 101 * 102 * @return The {@link org.apache.tapestry.IComponent} object this binding is set against. 103 * @since 4.0 104 */ 105 106 public Object getComponent() 107 { 108 return null; 109 } 110 111 /** @since 3.0 */ 112 113 protected BindingException createReadOnlyBindingException(IBinding binding) 114 { 115 return new BindingException(BindingMessages.readOnlyBinding(binding), binding); 116 } 117 118 /** @since 4.0 */ 119 120 public String getDescription() 121 { 122 return _description; 123 } 124 125 /** 126 * Gets the converter used to coerce binding values in to their target types. 127 * 128 * @return The {@link ValueConverter} being used by this binding. 129 */ 130 public ValueConverter getValueConverter() 131 { 132 return _valueConverter; 133 } 134 135 public String toString() 136 { 137 StringBuffer buffer = new StringBuffer(); 138 buffer.append(getClass().getName()); 139 buffer.append("@"); 140 buffer.append(Integer.toHexString(hashCode())); 141 buffer.append("["); 142 buffer.append(_description); 143 144 extendDescription(buffer); 145 146 buffer.append(", location="); 147 buffer.append(_location); 148 buffer.append("]"); 149 150 return buffer.toString(); 151 } 152 153 /** 154 * Does nothing, subclasses may override to add additional information. 155 */ 156 protected void extendDescription(StringBuffer buffer) 157 { 158 159 } 160 }