001 // Copyright 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.transform;
016
017 import org.apache.tapestry5.annotations.SessionAttribute;
018 import org.apache.tapestry5.model.MutableComponentModel;
019 import org.apache.tapestry5.plastic.FieldConduit;
020 import org.apache.tapestry5.plastic.InstanceContext;
021 import org.apache.tapestry5.plastic.PlasticClass;
022 import org.apache.tapestry5.plastic.PlasticField;
023 import org.apache.tapestry5.services.Request;
024 import org.apache.tapestry5.services.Session;
025 import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
026 import org.apache.tapestry5.services.transform.TransformationSupport;
027
028 /**
029 * Looks for the {@link SessionAttribute} annotation and converts read and write access on such
030 * fields into calls to the {@link Session#getAttribute(String)} and {@link Session#setAttribute(String, Object)}.
031 */
032 public class SessionAttributeWorker implements ComponentClassTransformWorker2
033 {
034 private final Request request;
035
036 private class SessionKeyConduit implements FieldConduit<Object>
037 {
038 private final String key;
039
040 public SessionKeyConduit(String key)
041 {
042 this.key = key;
043 }
044
045 public Object get(Object instance, InstanceContext context)
046 {
047 Session session = getSession();
048
049 if (session == null)
050 {
051 return null;
052 }
053
054 return session.getAttribute(key);
055 }
056
057 public void set(Object instance, InstanceContext context, Object newValue)
058 {
059 request.getSession(true).setAttribute(key, newValue);
060 }
061
062 private Session getSession()
063 {
064 return request.getSession(false);
065 }
066 }
067
068 public SessionAttributeWorker(Request request)
069 {
070 this.request = request;
071 }
072
073
074 public void transform(PlasticClass plasticClass, TransformationSupport support, MutableComponentModel model)
075 {
076 for (PlasticField field : plasticClass.getFieldsWithAnnotation(SessionAttribute.class))
077 {
078 convertFieldToSessionAccess(field);
079 }
080 }
081
082 private void convertFieldToSessionAccess(PlasticField field)
083 {
084 SessionAttribute annotation = field.getAnnotation(SessionAttribute.class);
085
086 field.claim(annotation);
087
088 String key = determineSessionKey(field, annotation.value());
089
090 field.setConduit(new SessionKeyConduit(key));
091 }
092
093 private String determineSessionKey(PlasticField field, String value)
094 {
095 return value.equals("") ? field.getName() : value;
096 }
097 }