001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.servlet;
016    
017    import com.liferay.portal.kernel.util.CookieUtil;
018    import com.liferay.portal.kernel.util.HashUtil;
019    import com.liferay.portal.kernel.util.StringPool;
020    
021    import java.io.Externalizable;
022    import java.io.IOException;
023    import java.io.ObjectInput;
024    import java.io.ObjectOutput;
025    
026    import java.util.Objects;
027    
028    import javax.servlet.http.Cookie;
029    import javax.servlet.http.HttpServletResponse;
030    
031    /**
032     * @author Michael Young
033     * @author Shuyang Zhou
034     */
035    public class Header implements Externalizable {
036    
037            /**
038             * The empty constructor is required by {@link Externalizable}. Do not use
039             * this for any other purpose.
040             */
041            public Header() {
042            }
043    
044            public Header(Cookie cookie) {
045                    if (cookie == null) {
046                            throw new IllegalArgumentException("Cookie is null");
047                    }
048    
049                    _type = Type.COOKIE;
050    
051                    _cookieValue = cookie;
052            }
053    
054            public Header(int integer) {
055                    _type = Type.INTEGER;
056    
057                    _intValue = integer;
058            }
059    
060            public Header(long date) {
061                    _type = Type.DATE;
062    
063                    _dateValue = date;
064            }
065    
066            public Header(String string) {
067                    if (string == null) {
068                            throw new IllegalArgumentException("String is null");
069                    }
070    
071                    _type = Type.STRING;
072    
073                    _stringValue = string;
074            }
075    
076            public void addToResponse(String key, HttpServletResponse response) {
077                    if (_type == Type.COOKIE) {
078                            response.addCookie(_cookieValue);
079                    }
080                    else if (_type == Type.DATE) {
081                            response.addDateHeader(key, _dateValue);
082                    }
083                    else if (_type == Type.INTEGER) {
084                            response.addIntHeader(key, _intValue);
085                    }
086                    else if (_type == Type.STRING) {
087                            response.addHeader(key, _stringValue);
088                    }
089                    else {
090                            throw new IllegalStateException("Invalid type " + _type);
091                    }
092            }
093    
094            @Override
095            public boolean equals(Object obj) {
096                    if (this == obj) {
097                            return true;
098                    }
099    
100                    if (!(obj instanceof Header)) {
101                            return false;
102                    }
103    
104                    Header header = (Header)obj;
105    
106                    if (_type != header._type) {
107                            return false;
108                    }
109    
110                    if (_type == Type.COOKIE) {
111                            return _equals(_cookieValue, header._cookieValue);
112                    }
113                    else if (_type == Type.DATE) {
114                            if (_dateValue == header._dateValue) {
115                                    return true;
116                            }
117    
118                            return false;
119                    }
120                    else if (_type == Type.INTEGER) {
121                            if (_intValue == header._intValue) {
122                                    return true;
123                            }
124    
125                            return false;
126                    }
127                    else if (_type == Type.STRING) {
128                            return _stringValue.equals(header._stringValue);
129                    }
130                    else {
131                            throw new IllegalStateException("Invalid type " + _type);
132                    }
133            }
134    
135            @Override
136            public int hashCode() {
137                    if (_type == Type.COOKIE) {
138                            return _hashCode(_cookieValue);
139                    }
140                    else if (_type == Type.DATE) {
141                            return (int)(_dateValue ^ (_dateValue >>> 32));
142                    }
143                    else if (_type == Type.INTEGER) {
144                            return _intValue;
145                    }
146                    else if (_type == Type.STRING) {
147                            return _stringValue.hashCode();
148                    }
149                    else {
150                            throw new IllegalStateException("Invalid type " + _type);
151                    }
152            }
153    
154            @Override
155            public void readExternal(ObjectInput objectInput) throws IOException {
156                    if (objectInput.readBoolean()) {
157                            int size = objectInput.readInt();
158    
159                            byte[] data = new byte[size];
160    
161                            objectInput.readFully(data);
162    
163                            _cookieValue = CookieUtil.deserialize(data);
164                    }
165    
166                    _dateValue = objectInput.readLong();
167                    _intValue = objectInput.readInt();
168    
169                    String stringValue = objectInput.readUTF();
170    
171                    if (!stringValue.isEmpty()) {
172                            _stringValue = stringValue;
173                    }
174    
175                    _type = Type.values()[objectInput.readInt()];
176            }
177    
178            public void setToResponse(String key, HttpServletResponse response) {
179                    if (_type == Type.COOKIE) {
180                            response.addCookie(_cookieValue);
181                    }
182                    else if (_type == Type.DATE) {
183                            response.setDateHeader(key, _dateValue);
184                    }
185                    else if (_type == Type.INTEGER) {
186                            response.setIntHeader(key, _intValue);
187                    }
188                    else if (_type == Type.STRING) {
189                            response.setHeader(key, _stringValue);
190                    }
191                    else {
192                            throw new IllegalStateException("Invalid type " + _type);
193                    }
194            }
195    
196            @Override
197            public String toString() {
198                    if (_type == Type.COOKIE) {
199                            return CookieUtil.toString(_cookieValue);
200                    }
201                    else if (_type == Type.DATE) {
202                            return String.valueOf(_dateValue);
203                    }
204                    else if (_type == Type.INTEGER) {
205                            return String.valueOf(_intValue);
206                    }
207                    else if (_type == Type.STRING) {
208                            return _stringValue;
209                    }
210                    else {
211                            throw new IllegalStateException("Invalid type " + _type);
212                    }
213            }
214    
215            @Override
216            public void writeExternal(ObjectOutput objectOutput) throws IOException {
217                    if (_cookieValue == null) {
218                            objectOutput.writeBoolean(false);
219                    }
220                    else {
221                            objectOutput.writeBoolean(true);
222    
223                            byte[] data = CookieUtil.serialize(_cookieValue);
224    
225                            objectOutput.writeInt(data.length);
226                            objectOutput.write(data);
227                    }
228    
229                    objectOutput.writeLong(_dateValue);
230                    objectOutput.writeInt(_intValue);
231    
232                    if (_stringValue == null) {
233                            objectOutput.writeUTF(StringPool.BLANK);
234                    }
235                    else {
236                            objectOutput.writeUTF(_stringValue);
237                    }
238    
239                    objectOutput.writeInt(_type.ordinal());
240            }
241    
242            private boolean _equals(Cookie cookie1, Cookie cookie2) {
243                    if (cookie1 == cookie2) {
244                            return true;
245                    }
246    
247                    if (!Objects.equals(cookie1.getComment(), cookie2.getComment()) ||
248                            !Objects.equals(cookie1.getDomain(), cookie2.getDomain()) ||
249                            (cookie1.getMaxAge() != cookie2.getMaxAge()) ||
250                            !Objects.equals(cookie1.getName(), cookie2.getName()) ||
251                            !Objects.equals(cookie1.getPath(), cookie2.getPath()) ||
252                            (cookie1.getSecure() != cookie2.getSecure()) ||
253                            !Objects.equals(cookie1.getValue(), cookie2.getValue()) ||
254                            (cookie1.getVersion() != cookie2.getVersion())) {
255    
256                            return false;
257                    }
258    
259                    return true;
260            }
261    
262            private int _hashCode(Cookie cookie) {
263                    int hashCode = HashUtil.hash(0, cookie.getComment());
264    
265                    hashCode = HashUtil.hash(hashCode, cookie.getDomain());
266                    hashCode = HashUtil.hash(hashCode, cookie.getMaxAge());
267                    hashCode = HashUtil.hash(hashCode, cookie.getName());
268                    hashCode = HashUtil.hash(hashCode, cookie.getPath());
269                    hashCode = HashUtil.hash(hashCode, cookie.getSecure());
270                    hashCode = HashUtil.hash(hashCode, cookie.getValue());
271                    hashCode = HashUtil.hash(hashCode, cookie.getVersion());
272    
273                    return hashCode;
274            }
275    
276            private Cookie _cookieValue;
277            private long _dateValue;
278            private int _intValue;
279            private String _stringValue;
280            private Type _type;
281    
282            private static enum Type {
283    
284                    COOKIE, DATE, INTEGER, STRING
285    
286            }
287    
288    }