    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    }