001// Copyright 2007, 2008, 2012 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 javax.servlet.http.Cookie;
018
019import org.apache.tapestry5.CookieBuilder;
020import org.apache.tapestry5.SymbolConstants;
021import org.apache.tapestry5.commons.util.TimeInterval;
022import org.apache.tapestry5.http.TapestryHttpSymbolConstants;
023import org.apache.tapestry5.http.services.Request;
024import org.apache.tapestry5.ioc.annotations.IntermediateType;
025import org.apache.tapestry5.ioc.annotations.Symbol;
026import org.apache.tapestry5.services.Cookies;
027
028/**
029 * Implementation of the {@link org.apache.tapestry5.services.Cookies} service interface.
030 */
031public class CookiesImpl implements Cookies
032{
033    private final Request request;
034
035    private final CookieSource cookieSource;
036
037    private final CookieSink cookieSink;
038
039    private final String defaultCookiePath;
040
041    private final int defaultMaxAge;
042
043    /**
044     * @param request
045     * @param cookieSource
046     * @param cookieSink
047     * @param contextPath
048     * @param defaultMaxAge
049     *         default cookie expiration time in milliseconds
050     */
051    public CookiesImpl(Request request,
052
053                       CookieSource cookieSource,
054
055                       CookieSink cookieSink,
056
057                       @Symbol(TapestryHttpSymbolConstants.CONTEXT_PATH)
058                       String contextPath,
059
060                       @Symbol(SymbolConstants.COOKIE_MAX_AGE) @IntermediateType(TimeInterval.class)
061                       long defaultMaxAge)
062    {
063        this.request = request;
064        this.cookieSource = cookieSource;
065        this.cookieSink = cookieSink;
066        this.defaultCookiePath = contextPath + "/";
067        this.defaultMaxAge = (int) (defaultMaxAge / 1000l);
068    }
069
070    public String readCookieValue(String name)
071    {
072        Cookie[] cookies = cookieSource.getCookies();
073
074        if (cookies == null) return null;
075
076        for (Cookie cooky : cookies)
077        {
078            if (cooky.getName().equals(name)) return cooky.getValue();
079        }
080
081        return null;
082    }
083
084    public void writeCookieValue(String name, String value)
085    {
086        getBuilder(name, value).write();
087    }
088
089    public void writeCookieValue(String name, String value, int maxAge)
090    {
091        getBuilder(name, value).setMaxAge(maxAge).write();
092    }
093
094    public void writeCookieValue(String name, String value, String path)
095    {
096        getBuilder(name, value).setPath(path).write();
097    }
098
099    public void writeDomainCookieValue(String name, String value, String domain)
100    {
101        getBuilder(name, value).setDomain(domain).write();
102    }
103
104    public void writeDomainCookieValue(String name, String value, String domain, int maxAge)
105    {
106        getBuilder(name, value).setDomain(domain).setMaxAge(maxAge).write();
107    }
108
109    public void writeCookieValue(String name, String value, String path, String domain)
110    {
111        getBuilder(name, value).setPath(path).setDomain(domain).write();
112    }
113
114    public void removeCookieValue(String name)
115    {
116        getBuilder(name, null).delete();
117    }
118
119    public CookieBuilder getBuilder(String name, String value)
120    {
121        CookieBuilder builder = new CookieBuilder(name, value)
122        {
123            @Override
124            public void write()
125            {
126                Cookie cookie = new Cookie(name, value);
127
128                cookie.setPath(path == null ? defaultCookiePath : path);
129
130                if(domain != null)
131                    cookie.setDomain(domain);
132
133                cookie.setMaxAge(maxAge == null ? defaultMaxAge : maxAge);
134
135                cookie.setSecure(secure == null ? request.isSecure() : secure);
136
137                cookie.setVersion(version);
138
139                if (comment != null)
140                {
141                    cookie.setComment(comment);
142                }
143
144                if (httpOnly != null)
145                {
146                    cookie.setHttpOnly(httpOnly);
147                }
148
149                cookieSink.addCookie(cookie);
150            }
151
152            @Override
153            public void delete()
154            {
155                setMaxAge(0);
156
157                write();
158            }
159        };
160
161        return builder;
162    }
163}