Return-Path: X-Original-To: apmail-chemistry-commits-archive@www.apache.org Delivered-To: apmail-chemistry-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 92A791783E for ; Mon, 6 Apr 2015 17:10:58 +0000 (UTC) Received: (qmail 21482 invoked by uid 500); 6 Apr 2015 17:10:58 -0000 Delivered-To: apmail-chemistry-commits-archive@chemistry.apache.org Received: (qmail 21379 invoked by uid 500); 6 Apr 2015 17:10:58 -0000 Mailing-List: contact commits-help@chemistry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@chemistry.apache.org Delivered-To: mailing list commits@chemistry.apache.org Received: (qmail 19714 invoked by uid 99); 6 Apr 2015 17:10:57 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Apr 2015 17:10:57 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id 1E3B2AC0163 for ; Mon, 6 Apr 2015 17:10:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1671596 [35/46] - in /chemistry/site/trunk/content/java/0.13.0/maven/chemistry-opencmis-client/chemistry-opencmis-client-bindings: ./ css/ images/ images/logos/ xref-test/ xref-test/org/ xref-test/org/apache/ xref-test/org/apache/chemistry... Date: Mon, 06 Apr 2015 17:10:52 -0000 To: commits@chemistry.apache.org From: gabriele@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150406171057.1E3B2AC0163@hades.apache.org> Added: chemistry/site/trunk/content/java/0.13.0/maven/chemistry-opencmis-client/chemistry-opencmis-client-bindings/xref/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.html URL: http://svn.apache.org/viewvc/chemistry/site/trunk/content/java/0.13.0/maven/chemistry-opencmis-client/chemistry-opencmis-client-bindings/xref/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.html?rev=1671596&view=auto ============================================================================== --- chemistry/site/trunk/content/java/0.13.0/maven/chemistry-opencmis-client/chemistry-opencmis-client-bindings/xref/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.html (added) +++ chemistry/site/trunk/content/java/0.13.0/maven/chemistry-opencmis-client/chemistry-opencmis-client-bindings/xref/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.html Mon Apr 6 17:10:50 2015 @@ -0,0 +1,806 @@ + + + + +CmisHttpCookie xref + + + +
+
+1   /*
+2    * Licensed to the Apache Software Foundation (ASF) under one
+3    * or more contributor license agreements.  See the NOTICE file
+4    * distributed with this work for additional information
+5    * regarding copyright ownership.  The ASF licenses this file
+6    * to you under the Apache License, Version 2.0 (the
+7    * "License"); you may not use this file except in compliance
+8    * with the License.  You may obtain a copy of the License at
+9    *
+10   * http://www.apache.org/licenses/LICENSE-2.0
+11   *
+12   * Unless required by applicable law or agreed to in writing,
+13   * software distributed under the License is distributed on an
+14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+15   * KIND, either express or implied.  See the License for the
+16   * specific language governing permissions and limitations
+17   * under the License.
+18   */
+19  /*
+20   * This class has been taken from Apache Harmony (http://harmony.apache.org/) 
+21   * and has been modified to work with OpenCMIS.
+22   */
+23  package org.apache.chemistry.opencmis.client.bindings.spi.cookies;
+24  
+25  import java.io.Serializable;
+26  import java.util.ArrayList;
+27  import java.util.Date;
+28  import java.util.HashMap;
+29  import java.util.List;
+30  import java.util.Locale;
+31  import java.util.Map;
+32  import java.util.regex.Matcher;
+33  import java.util.regex.Pattern;
+34  
+35  import org.apache.chemistry.opencmis.commons.impl.DateTimeHelper;
+36  
+37  /**
+38   * This class represents a http cookie, which indicates the status information
+39   * between the client agent side and the server side. According to RFC, there
+40   * are 4 http cookie specifications. This class is compatible with the original
+41   * Netscape specification, RFC 2109, RFC 2965 and party compatible with RFC
+42   * 6265. HttpCookie class can accept all syntax forms.
+43   */
+44  public final class CmisHttpCookie implements Cloneable, Serializable {
+45  
+46      private static final long serialVersionUID = 1L;
+47  
+48      private static final String DOT_STR = ".";
+49      private static final String LOCAL_STR = ".local";
+50      private static final String QUOTE_STR = "\"";
+51      private static final String COMMA_STR = ",";
+52      private static final Pattern HEAD_PATTERN = Pattern.compile("Set-Cookie2?:", Pattern.CASE_INSENSITIVE);
+53      private static final Pattern NAME_PATTERN = Pattern.compile(
+54              "([^$=,\u0085\u2028\u2029][^,\n\t\r\r\n\u0085\u2028\u2029]*?)=([^;]*)(;)?", Pattern.DOTALL
+55                      | Pattern.CASE_INSENSITIVE);
+56      private static final Pattern ATTR_PATTERN0 = Pattern.compile("([^;=]*)(?:=([^;]*))?");
+57      private static final Pattern ATTR_PATTERN1 = Pattern.compile("(,?[^;=]*)(?:=([^;,]*))?((?=.))?");
+58  
+59      private abstract static class Setter {
+60          private boolean set;
+61  
+62          Setter() {
+63              set = false;
+64          }
+65  
+66          boolean isSet() {
+67              return set;
+68          }
+69  
+70          void set(boolean isSet) {
+71              set = isSet;
+72          }
+73  
+74          abstract void setValue(String value, CmisHttpCookie cookie);
+75  
+76          void validate(String value, CmisHttpCookie cookie) {
+77              if (cookie.getVersion() == 1 && value != null && value.contains(COMMA_STR)) {
+78                  throw new IllegalArgumentException();
+79              }
+80          }
+81      }
+82  
+83      private Map<String, Setter> attributeSet = new HashMap<String, Setter>();
+84  
+85      /**
+86       * A utility method used to check whether the host name is in a domain or
+87       * not.
+88       * 
+89       * @param domain
+90       *            the domain to be checked against
+91       * @param host
+92       *            the host to be checked
+93       * @return true if the host is in the domain, false otherwise
+94       */
+95      public static boolean domainMatches(String domain, String host) {
+96          if (domain == null || host == null) {
+97              return false;
+98          }
+99          String newDomain = domain.toLowerCase();
+100         String newHost = host.toLowerCase();
+101 
+102         return newDomain.equals(newHost)
+103                 || (isValidDomain(newDomain) && effDomainMatches(newDomain, newHost) && isValidHost(newDomain, newHost));
+104     }
+105 
+106     private static boolean effDomainMatches(String domain, String host) {
+107         // calculate effective host name
+108         String effHost = host.indexOf(DOT_STR) != -1 ? host : (host + LOCAL_STR);
+109 
+110         // Rule 2: domain and host are string-compare equal, or A = NB, B = .B'
+111         // and N is a non-empty name string
+112         boolean inDomain = domain.equals(effHost);
+113         inDomain = inDomain
+114                 || (effHost.endsWith(domain) && effHost.length() > domain.length() && domain.startsWith(DOT_STR));
+115 
+116         return inDomain;
+117     }
+118 
+119     private static boolean isCommaDelim(CmisHttpCookie cookie) {
+120         String value = cookie.getValue();
+121         if (value.startsWith(QUOTE_STR) && value.endsWith(QUOTE_STR)) {
+122             cookie.setValue(value.substring(1, value.length() - 1));
+123             return false;
+124         }
+125 
+126         if (cookie.getVersion() == 1 && value.contains(COMMA_STR)) {
+127             cookie.setValue(value.substring(0, value.indexOf(COMMA_STR)));
+128             return true;
+129         }
+130 
+131         return false;
+132     }
+133 
+134     private static boolean isValidDomain(String domain) {
+135         // Rule 1: The value for Domain contains embedded dots, or is .local
+136         if (domain.length() <= 2) {
+137             return false;
+138         }
+139 
+140         return domain.substring(1, domain.length() - 1).indexOf(DOT_STR) != -1 || domain.equals(LOCAL_STR);
+141     }
+142 
+143     private static boolean isValidHost(String domain, String host) {
+144         // Rule 3: host does not end with domain, or the remainder does not
+145         // contain "."
+146         boolean matches = !host.endsWith(domain);
+147         if (!matches) {
+148             String hostSub = host.substring(0, host.length() - domain.length());
+149             matches = hostSub.indexOf(DOT_STR) == -1;
+150         }
+151 
+152         return matches;
+153     }
+154 
+155     /**
+156      * Constructs a cookie from a string. The string should comply with
+157      * set-cookie or set-cookie2 header format as specified in RFC 2965. Since
+158      * set-cookies2 syntax allows more than one cookie definitions in one
+159      * header, the returned object is a list.
+160      * 
+161      * @param header
+162      *            a set-cookie or set-cookie2 header.
+163      * @return a list of constructed cookies
+164      * @throws IllegalArgumentException
+165      *             if the string does not comply with cookie specification, or
+166      *             the cookie name contains illegal characters, or reserved
+167      *             tokens of cookie specification appears
+168      * @throws NullPointerException
+169      *             if header is null
+170      */
+171     public static List<CmisHttpCookie> parse(String header) {
+172         Matcher matcher = HEAD_PATTERN.matcher(header);
+173         // Parse cookie name & value
+174         List<CmisHttpCookie> list = null;
+175         CmisHttpCookie cookie = null;
+176         String headerString = header;
+177         int version = 0;
+178         // process set-cookie | set-cookie2 head
+179         if (matcher.find()) {
+180             String cookieHead = matcher.group();
+181             if ("set-cookie2:".equalsIgnoreCase(cookieHead)) {
+182                 version = 1;
+183             }
+184             headerString = header.substring(cookieHead.length());
+185         }
+186 
+187         // parse cookie name/value pair
+188         matcher = NAME_PATTERN.matcher(headerString);
+189         if (matcher.lookingAt()) {
+190             list = new ArrayList<CmisHttpCookie>();
+191             cookie = new CmisHttpCookie(matcher.group(1), matcher.group(2));
+192             cookie.setVersion(version);
+193 
+194             /*
+195              * Comma is a delimiter in cookie spec 1.1. If find comma in version
+196              * 1 cookie header, part of matched string need to be spitted out.
+197              */
+198             String nameGroup = matcher.group();
+199             if (isCommaDelim(cookie)) {
+200                 headerString = headerString.substring(nameGroup.indexOf(COMMA_STR));
+201             } else {
+202                 headerString = headerString.substring(nameGroup.length());
+203             }
+204             list.add(cookie);
+205         } else {
+206             throw new IllegalArgumentException();
+207         }
+208 
+209         // parse cookie headerString
+210         while (!(headerString.length() == 0)) {
+211             matcher = cookie.getVersion() == 1 ? ATTR_PATTERN1.matcher(headerString) : ATTR_PATTERN0
+212                     .matcher(headerString);
+213 
+214             if (matcher.lookingAt()) {
+215                 String attrName = matcher.group(1).trim();
+216 
+217                 // handle special situation like: <..>;;<..>
+218                 if (attrName.length() == 0) {
+219                     headerString = headerString.substring(1);
+220                     continue;
+221                 }
+222 
+223                 // If port is the attribute, then comma will not be used as a
+224                 // delimiter
+225                 if (attrName.equalsIgnoreCase("port") || attrName.equalsIgnoreCase("expires")) {
+226                     int start = matcher.regionStart();
+227                     matcher = ATTR_PATTERN0.matcher(headerString);
+228                     matcher.region(start, headerString.length());
+229                     matcher.lookingAt();
+230                 } else if (cookie.getVersion() == 1 && attrName.startsWith(COMMA_STR)) {
+231                     // If the last encountered token is comma, and the parsed
+232                     // attribute is not port, then this attribute/value pair
+233                     // ends.
+234                     headerString = headerString.substring(1);
+235                     matcher = NAME_PATTERN.matcher(headerString);
+236                     if (matcher.lookingAt()) {
+237                         cookie = new CmisHttpCookie(matcher.group(1), matcher.group(2));
+238                         list.add(cookie);
+239                         headerString = headerString.substring(matcher.group().length());
+240                         continue;
+241                     }
+242                 }
+243 
+244                 Setter setter = cookie.attributeSet.get(attrName.toLowerCase());
+245                 if (setter != null && !setter.isSet()) {
+246                     String attrValue = matcher.group(2);
+247                     setter.validate(attrValue, cookie);
+248                     setter.setValue(matcher.group(2), cookie);
+249                 }
+250                 headerString = headerString.substring(matcher.end());
+251             }
+252         }
+253 
+254         return list;
+255     }
+256 
+257     private String comment;
+258     private String commentURL;
+259     private boolean discard;
+260     private String domain;
+261     private long maxAge = -1L;
+262     private String name;
+263     private String path;
+264     private String portList;
+265     private boolean secure;
+266     private String value;
+267     private int version = 1;
+268 
+269     {
+270         attributeSet.put("comment", new Setter() {
+271             @Override
+272             void setValue(String value, CmisHttpCookie cookie) {
+273                 cookie.setComment(value);
+274                 if (cookie.getComment() != null) {
+275                     set(true);
+276                 }
+277             }
+278         });
+279         attributeSet.put("commenturl", new Setter() {
+280             @Override
+281             void setValue(String value, CmisHttpCookie cookie) {
+282                 cookie.setCommentURL(value);
+283                 if (cookie.getCommentURL() != null) {
+284                     set(true);
+285                 }
+286             }
+287         });
+288         attributeSet.put("discard", new Setter() {
+289             @Override
+290             void setValue(String value, CmisHttpCookie cookie) {
+291                 cookie.setDiscard(true);
+292                 set(true);
+293             }
+294         });
+295         attributeSet.put("domain", new Setter() {
+296             @Override
+297             void setValue(String value, CmisHttpCookie cookie) {
+298                 cookie.setDomain(value);
+299                 if (cookie.getDomain() != null) {
+300                     set(true);
+301                 }
+302             }
+303         });
+304         attributeSet.put("max-age", new Setter() {
+305             @Override
+306             void setValue(String value, CmisHttpCookie cookie) {
+307                 try {
+308                     cookie.setMaxAge(Long.parseLong(value));
+309                 } catch (NumberFormatException e) {
+310                     throw new IllegalArgumentException("Invalid max-age!", e);
+311                 }
+312                 set(true);
+313 
+314                 if (!attributeSet.get("version").isSet()) {
+315                     cookie.setVersion(1);
+316                 }
+317             }
+318         });
+319 
+320         attributeSet.put("path", new Setter() {
+321             @Override
+322             void setValue(String value, CmisHttpCookie cookie) {
+323                 cookie.setPath(value);
+324                 if (cookie.getPath() != null) {
+325                     set(true);
+326                 }
+327             }
+328         });
+329         attributeSet.put("port", new Setter() {
+330             @Override
+331             void setValue(String value, CmisHttpCookie cookie) {
+332                 cookie.setPortlist(value);
+333                 if (cookie.getPortlist() != null) {
+334                     set(true);
+335                 }
+336             }
+337 
+338             @Override
+339             void validate(String v, CmisHttpCookie cookie) {
+340             }
+341         });
+342         attributeSet.put("secure", new Setter() {
+343             @Override
+344             void setValue(String value, CmisHttpCookie cookie) {
+345                 cookie.setSecure(true);
+346                 set(true);
+347             }
+348         });
+349         attributeSet.put("version", new Setter() {
+350             @Override
+351             void setValue(String value, CmisHttpCookie cookie) {
+352                 try {
+353                     int v = Integer.parseInt(value);
+354                     if (v > cookie.getVersion()) {
+355                         cookie.setVersion(v);
+356                     }
+357                 } catch (NumberFormatException e) {
+358                     throw new IllegalArgumentException("Invalid version!", e);
+359                 }
+360                 if (cookie.getVersion() != 0) {
+361                     set(true);
+362                 }
+363             }
+364         });
+365 
+366         attributeSet.put("expires", new Setter() {
+367             @Override
+368             void setValue(String value, CmisHttpCookie cookie) {
+369                 cookie.setVersion(0);
+370                 attributeSet.get("version").set(true);
+371                 if (!attributeSet.get("max-age").isSet()) {
+372                     attributeSet.get("max-age").set(true);
+373                     if (!"en".equalsIgnoreCase(Locale.getDefault().getLanguage())) {
+374                         cookie.setMaxAge(0);
+375                         return;
+376                     }
+377 
+378                     Date date = DateTimeHelper.parseHttpDateTime(value);
+379                     if (date != null) {
+380                         cookie.setMaxAge((date.getTime() - System.currentTimeMillis()) / 1000);
+381                     } else {
+382                         cookie.setMaxAge(0);
+383                     }
+384                 }
+385             }
+386 
+387             @Override
+388             void validate(String v, CmisHttpCookie cookie) {
+389             }
+390         });
+391     }
+392 
+393     /**
+394      * Initializes a cookie with the specified name and value.
+395      * 
+396      * The name attribute can just contain ASCII characters, which is immutable
+397      * after creation. Commas, white space and semicolons are not allowed. The $
+398      * character is also not allowed to be the beginning of the name.
+399      * 
+400      * The value attribute depends on what the server side is interested. The
+401      * setValue method can be used to change it.
+402      * 
+403      * RFC 2965 is the default cookie specification of this class. If one wants
+404      * to change the version of the cookie, the setVersion method is available.
+405      * 
+406      * @param name
+407      *            - the specific name of the cookie
+408      * @param value
+409      *            - the specific value of the cookie
+410      * 
+411      * @throws IllegalArgumentException
+412      *             - if the name contains not-allowed or reserved characters
+413      * 
+414      * @throws NullPointerException
+415      *             if the value of name is null
+416      */
+417     public CmisHttpCookie(String name, String value) {
+418         String ntrim = name.trim(); // erase leading and trailing whitespaces
+419         if (!isValidName(ntrim)) {
+420             throw new IllegalArgumentException("Invalid name!");
+421         }
+422 
+423         this.name = ntrim;
+424         this.value = value;
+425     }
+426 
+427     private void attrToString(StringBuilder builder, String attrName, String attrValue) {
+428         if (attrValue != null && builder != null) {
+429             builder.append(';');
+430             builder.append('$');
+431             builder.append(attrName);
+432             builder.append("=\"");
+433             builder.append(attrValue);
+434             builder.append(QUOTE_STR);
+435         }
+436     }
+437 
+438     /**
+439      * Answers a copy of this object.
+440      * 
+441      * @return a copy of this cookie
+442      */
+443     @Override
+444     public Object clone() {
+445         try {
+446             return super.clone();
+447         } catch (CloneNotSupportedException e) {
+448             return null;
+449         }
+450     }
+451 
+452     /**
+453      * Answers whether two cookies are equal. Two cookies are equal if they have
+454      * the same domain and name in a case-insensitive mode and path in a
+455      * case-sensitive mode.
+456      * 
+457      * @param obj
+458      *            the object to be compared.
+459      * @return true if two cookies equals, false otherwise
+460      */
+461     @Override
+462     public boolean equals(Object obj) {
+463         if (obj == this) {
+464             return true;
+465         }
+466         if (obj instanceof CmisHttpCookie) {
+467             CmisHttpCookie anotherCookie = (CmisHttpCookie) obj;
+468             if (name.equalsIgnoreCase(anotherCookie.getName())) {
+469                 String anotherDomain = anotherCookie.getDomain();
+470                 boolean equals = domain == null ? anotherDomain == null : domain.equalsIgnoreCase(anotherDomain);
+471                 if (equals) {
+472                     String anotherPath = anotherCookie.getPath();
+473                     return path == null ? anotherPath == null : path.equals(anotherPath);
+474                 }
+475             }
+476         }
+477         return false;
+478     }
+479 
+480     /**
+481      * Answers the value of comment attribute(specified in RFC 2965) of this
+482      * cookie.
+483      * 
+484      * @return the value of comment attribute
+485      */
+486     public String getComment() {
+487         return comment;
+488     }
+489 
+490     /**
+491      * Answers the value of commentURL attribute(specified in RFC 2965) of this
+492      * cookie.
+493      * 
+494      * @return the value of commentURL attribute
+495      */
+496     public String getCommentURL() {
+497         return commentURL;
+498     }
+499 
+500     /**
+501      * Answers the value of discard attribute(specified in RFC 2965) of this
+502      * cookie.
+503      * 
+504      * @return discard value of this cookie
+505      */
+506     public boolean getDiscard() {
+507         return discard;
+508     }
+509 
+510     /**
+511      * Answers the domain name for this cookie in the format specified in RFC
+512      * 2965
+513      * 
+514      * @return the domain value of this cookie
+515      */
+516     public String getDomain() {
+517         return domain;
+518     }
+519 
+520     /**
+521      * Returns the Max-Age value as specified in RFC 2965 of this cookie.
+522      * 
+523      * @return the Max-Age value
+524      */
+525     public long getMaxAge() {
+526         return maxAge;
+527     }
+528 
+529     /**
+530      * Answers the name for this cookie.
+531      * 
+532      * @return the name for this cookie
+533      */
+534     public String getName() {
+535         return name;
+536     }
+537 
+538     /**
+539      * Answers the path part of a request URL to which this cookie is returned.
+540      * This cookie is visible to all subpaths.
+541      * 
+542      * @return the path used to return the cookie
+543      */
+544     public String getPath() {
+545         return path;
+546     }
+547 
+548     /**
+549      * Answers the value of port attribute(specified in RFC 2965) of this
+550      * cookie.
+551      * 
+552      * @return port list of this cookie
+553      */
+554     public String getPortlist() {
+555         return portList;
+556     }
+557 
+558     /**
+559      * Answers true if the browser only sends cookies over a secure protocol.
+560      * False if can send cookies through any protocols.
+561      * 
+562      * @return true if sends cookies only through secure protocol, false
+563      *         otherwise
+564      */
+565     public boolean getSecure() {
+566         return secure;
+567     }
+568 
+569     /**
+570      * Answers the value of this cookie.
+571      * 
+572      * @return the value of this cookie
+573      */
+574     public String getValue() {
+575         return value;
+576     }
+577 
+578     /**
+579      * Get the version of this cookie
+580      * 
+581      * @return 0 indicates the original Netscape cookie specification, while 1
+582      *         indicates RFC 2965/2109 specification.
+583      */
+584     public int getVersion() {
+585         return version;
+586     }
+587 
+588     /**
+589      * Answers whether the cookie has expired.
+590      * 
+591      * @return true is the cookie has expired, false otherwise
+592      */
+593     public boolean hasExpired() {
+594         // -1 indicates the cookie will persist until browser shutdown
+595         // so the cookie is not expired.
+596         if (maxAge == -1L) {
+597             return false;
+598         }
+599 
+600         boolean expired = false;
+601         if (maxAge <= 0L) {
+602             expired = true;
+603         }
+604         return expired;
+605     }
+606 
+607     /**
+608      * Answers hash code of this http cookie. The result is calculated as below:
+609      * 
+610      * getName().toLowerCase().hashCode() + getDomain().toLowerCase().hashCode()
+611      * + getPath().hashCode()
+612      * 
+613      * @return the hash code of this cookie
+614      */
+615     @Override
+616     public int hashCode() {
+617         int hashCode = name.toLowerCase().hashCode();
+618         hashCode += domain == null ? 0 : domain.toLowerCase().hashCode();
+619         hashCode += path == null ? 0 : path.hashCode();
+620         return hashCode;
+621     }
+622 
+623     private boolean isValidName(String n) {
+624         // name cannot be empty or begin with '$' or equals the reserved
+625         // attributes (case-insensitive)
+626         boolean isValid = !(n.length() == 0 || n.charAt(0) == '$' || attributeSet.containsKey(n.toLowerCase()));
+627         if (isValid) {
+628             for (int i = 0; i < n.length(); i++) {
+629                 char nameChar = n.charAt(i);
+630                 // name must be ASCII characters and cannot contain ';', ',' and
+631                 // whitespace
+632                 if (nameChar < 0 || nameChar >= 127 || nameChar == ';' || nameChar == ','
+633                         || (Character.isWhitespace(nameChar) && nameChar != ' ')) {
+634                     isValid = false;
+635                     break;
+636                 }
+637             }
+638         }
+639 
+640         return isValid;
+641     }
+642 
+643     /**
+644      * Set the value of comment attribute(specified in RFC 2965) of this cookie.
+645      * 
+646      * @param purpose
+647      *            the comment value to be set
+648      */
+649     public void setComment(String purpose) {
+650         comment = purpose;
+651     }
+652 
+653     /**
+654      * Set the value of commentURL attribute(specified in RFC 2965) of this
+655      * cookie.
+656      * 
+657      * @param purpose
+658      *            the value of commentURL attribute to be set
+659      */
+660     public void setCommentURL(String purpose) {
+661         commentURL = purpose;
+662     }
+663 
+664     /**
+665      * Set the value of discard attribute(specified in RFC 2965) of this cookie.
+666      * 
+667      * @param discard
+668      *            the value for discard attribute
+669      */
+670     public void setDiscard(boolean discard) {
+671         this.discard = discard;
+672     }
+673 
+674     /**
+675      * Set the domain value for this cookie. Browsers send the cookie to the
+676      * domain specified by this value. The form of the domain is specified in
+677      * RFC 2965.
+678      * 
+679      * @param pattern
+680      *            the domain pattern
+681      */
+682     public void setDomain(String pattern) {
+683         domain = pattern == null ? null : pattern.toLowerCase();
+684     }
+685 
+686     /**
+687      * Sets the Max-Age value as specified in RFC 2965 of this cookie to expire.
+688      * 
+689      * @param expiry
+690      *            the value used to set the Max-Age value of this cookie
+691      */
+692     public void setMaxAge(long expiry) {
+693         maxAge = expiry;
+694     }
+695 
+696     /**
+697      * Set the path to which this cookie is returned. This cookie is visible to
+698      * all the pages under the path and all subpaths.
+699      * 

[... 98 lines stripped ...]