package net.spatula.news;

/**-
 * Copyright (c) 2002 Nick Johnson
 * All rights reserved.
 *
 * The Spatula Public License:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted for non-commercial purposes, 
 * provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * For (3) and (4) below, "incorporated" means used in whole or part
 * in a derived work or used as a dependency of a separate work.
 *
 * 3. Neither source code or binary form may be incorporated into any
 *    work falling under a license which establishes mandatory licensing 
 *    requirements on derived works; for example, requiring any derived work 
 *    to use a particular license.
 * 4. Neither source code or binary form may be incorporated into any
 *    work which requires for its operation the installation of other works 
 *    which may fall under the restrictions given in (3) above.
 * 5. If this work is included or integrated, modified or unmodified,
 *    with a derived or separate work with a more restrictive license than 
 *    this one, this work must be included as a separate whole in either 
 *    source or binary form, according to the provisions in (1) and (2) 
 *    above.
 *
 * 6. This license is subject to periodic updates.  For the latest version
 *    of this license, visit http://spatula.net/license.txt
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $Id: PersistantCookie.java,v 1.2 2002/11/06 02:06:36 spatula Exp $
 *
 */

import javax.servlet.http.Cookie;
import java.net.URLDecoder;

/**
 * A cookie that keeps track of its expiration time, domain, and path
 * These values are normally not sent along with the cookie FROM the
 * browser, so once you've set them, it's impossible to find out
 * what they used to be.  This makes it hard to allow a cookie
 * to be updated, but to still get it to expire based on when
 * it was originally set.
 * @author Nick Johnson <spatulanews [at] spatula.net>
 * @see javax.servlet.http.Cookie
 */

public class PersistantCookie extends Cookie {

    private String value="";
    private int expires = -1;

    /**
      * Construct a persistant cookie using name and value
      */
    public PersistantCookie(String name, String value) {
	super(name, value);
	setValue(value);
    }

    /**
      * Construct a persistant cookie using the data from
      * an existing cookie
      */
    public PersistantCookie(Cookie c) {
	super(c.getName(), c.getValue());
	setValue(c.getValue());
    }

    public void setValue(String value) {
	int index = -1;
        value = URLDecoder.decode(value);
	if ((index = value.indexOf('\035'))  != -1) {
	    this.value = value.substring(0,index);
	    String meta = value.substring(index+1);
	    String[] metaData = meta.split("\036");
	    for (int i=0; i<metaData.length; i++) {
		String[] keyVal = metaData[i].split("\034");
		if (keyVal == null || keyVal.length != 2) {
		    continue;
		}
		String key = keyVal[0];
		String val = keyVal[1];
		if (key.equals("domain")) {
		    setDomain(val);
		} else if (key.equals("path")) {
		    setPath(val);
		} else if (key.equals("expires")) {
		    int time = (int)(System.currentTimeMillis() /1000);
		    int expires = Integer.parseInt(val);
		    this.expires = expires;
		    int lifespan = expires - time;
		    if (lifespan < 0) lifespan = 0;
		    setMaxAge(lifespan);
		}
	    }
	} else {
	    this.value = value;
	}
    }

    public String getValue() {
	if (expires < 0) {
	    int time = (int)(System.currentTimeMillis() / 1000);
	    expires = time + getMaxAge();
	}
	return Utils.urlEncode(value + "\035expires\034" + expires + "\036path\034" +
		getPath() + "\036domain\034" + getDomain());
    }

    /**
      * Return the internal representation of this cookie's value
      */
    public String getDataValue() {
	return value;
    }

}
