001 // Copyright 2008, 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.hibernate;
016
017 import org.apache.tapestry5.ValueEncoder;
018 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
019 import org.apache.tapestry5.ioc.services.PropertyAccess;
020 import org.apache.tapestry5.ioc.services.PropertyAdapter;
021 import org.apache.tapestry5.ioc.services.TypeCoercer;
022 import org.hibernate.Session;
023 import org.hibernate.mapping.PersistentClass;
024 import org.hibernate.mapping.Property;
025 import org.slf4j.Logger;
026
027 import java.io.Serializable;
028
029 public final class HibernateEntityValueEncoder<E> implements ValueEncoder<E>
030 {
031 private final Class<E> entityClass;
032
033 private final Session session;
034
035 private final TypeCoercer typeCoercer;
036
037 private final PropertyAdapter propertyAdapter;
038
039 private final Logger logger;
040
041 public HibernateEntityValueEncoder(Class<E> entityClass, PersistentClass persistentClass, Session session,
042 PropertyAccess propertyAccess, TypeCoercer typeCoercer, Logger logger)
043 {
044 this.entityClass = entityClass;
045 this.session = session;
046 this.typeCoercer = typeCoercer;
047 this.logger = logger;
048
049 Property property = persistentClass.getIdentifierProperty();
050
051 propertyAdapter = propertyAccess.getAdapter(this.entityClass).getPropertyAdapter(property.getName());
052 }
053
054 public String toClient(E value)
055 {
056 if (value == null)
057 return null;
058
059 Object id = propertyAdapter.get(value);
060
061 if (id == null)
062 {
063 return null;
064 }
065
066 return typeCoercer.coerce(id, String.class);
067 }
068
069 @SuppressWarnings("unchecked")
070 public E toValue(String clientValue)
071 {
072 if (InternalUtils.isBlank(clientValue))
073 return null;
074
075 Object id = null;
076
077 try
078 {
079
080 id = typeCoercer.coerce(clientValue, propertyAdapter.getType());
081 } catch (Exception ex)
082 {
083 throw new RuntimeException(String.format(
084 "Exception converting '%s' to instance of %s (id type for entity %s): %s", clientValue,
085 propertyAdapter.getType().getName(), entityClass.getName(), InternalUtils.toMessage(ex)), ex);
086 }
087
088 Serializable ser = (Serializable) id;
089
090 E result = (E) session.get(entityClass, ser);
091
092 if (result == null)
093 {
094 // We don't identify the entity type in the message because the logger is based on the
095 // entity type.
096 logger.error(String.format("Unable to convert client value '%s' into an entity instance.", clientValue));
097 }
098
099 return result;
100 }
101
102 }