001/*
002 * JPPF.
003 * Copyright (C) 2005-2015 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.net;
020
021import java.net.*;
022
023import org.jppf.utils.Range;
024
025
026/**
027 * Represents a pattern used for IPv6 addresses inclusion and exclusion lists.<br/>
028 * A pattern represents a single value or a range of values for each component of an IPv6 address.<br/>
029 * <p>Examples:
030 * <ul>
031 * <li>1080:0:0:0:8:800:200C:417A represents a single IPv6 address</li>
032 * <li>1080:0:0:0:8:800:200C represents all IPv6 addresses in the range 1080:0:0:0:8:800:200C:0 - 1080:0:0:0:8:800:200C:FFFF</li>
033 * <li>1080:0:0:0:8:800 represents all IPv6 addresses in the range 1080:0:0:0:8:800:0:0 - 1080:0:0:0:8:800:FFFF:FFFF</li>
034 * <li>1080:0:0:0:8:800:200C-20FF represents all IP addresses where the first component is equal to 1080, the second to 0, ..., the 7th component in the range 200C - 200FF, and the 8th in the range 0 - FFFF
035 * (equivalent to 1080:0:0:0:8:800:200C-20FF:0-FFFF)</li>
036 * </ul>
037 * <p>Syntax rules:
038 * <p>1. An empty component is considered as a 0-FFFF range. Examples:
039 * <ul>
040 * <li>:2:3:4:5:6:7:8 is equivalent to 0-FFFF:2:3:4:5:6:7:8</li>
041 * <li>1:2:3:4:5::7:8 is equivalent to 1:2:3:4:5:0-FFFF:7:8</li>
042 * <li>1:2:3:4:5:6:7: is equivalent to 1:2:3:4:5:6:7 and to 1:2:3:4:5:6:7:0-FFFF</li>
043 * </ul>
044 * <p>2. Ranges with missing bounds but still including the &quot;-&quot; sign are interpreted as a range with the lower bound
045 * equal to zero for a missing lower bound, and an upper bound equal to 0xFFFF if the upper bound is missing. Examples:
046 * <ul>
047 * <li>-128 is equivalent to 0-128</li>
048 * <li>12- is equivalent to 12-FFFF</li>
049 * <li>- is equivalent to an empty value and to 0-FFFF</li>
050 * </ul>
051 * <p>3. Valid values for range bounds and single values are positive integers in the range 0 ... 0xFFFF. A pattern containing any invalid value will be ignored.
052 * <p>4. A pattern describing more than 8 components or containing characters other than hexadecimal digits, '-', ':' or spaces will be ignored.
053 * @author Laurent Cohen
054 */
055public class IPv6AddressPattern extends AbstractIPAddressPattern
056{
057  /**
058   * Initialize this object with the specified string pattern.
059   * @param source the source pattern as a string.
060   * @throws IllegalArgumentException if the pattern is null or invalid.
061   */
062  public IPv6AddressPattern(final String source) throws IllegalArgumentException
063  {
064    super(source, PatternConfiguration.IPV6_CONFIGURATION);
065  }
066
067  @Override
068  public boolean matches(final InetAddress ip)
069  {
070    if (!(ip instanceof Inet6Address)) return false;
071    return super.matches(ip);
072  }
073
074  @Override
075  public String toString()
076  {
077    StringBuilder sb = new StringBuilder();
078    for (int i=0; i<ranges.size(); i++)
079    {
080      if (i > 0) sb.append(config.getCompSeparator());
081      Range<Integer> r = ranges.get(i);
082      sb.append(Integer.toHexString(r.getLower()));
083      if (!r.getLower().equals(r.getUpper())) sb.append('-').append(Integer.toHexString(r.getUpper()));
084    }
085    return sb.toString();
086  }
087
088  /**
089   * Main method.
090   * @param args not used.
091   */
092  public static void main(final String[] args)
093  {
094    System.out.println("***** IP v6 *****");
095    String[] ipv6patterns = { "1080:0:0:0:8:800:200C:417A", ":0::::::", "0:0:aa-bbcc:0:0:0:0:0", "1:2:3:4:5-:6:7:8", };
096    String ip = "1080:0:0:0:8:800:200C:417A";
097    for (int i=0; i<ipv6patterns.length; i++)
098    {
099      try
100      {
101        IPv6AddressPattern p = new IPv6AddressPattern(ipv6patterns[i]);
102        InetAddress addr = InetAddress.getByName(ip);
103        System.out.println("pattern " + i + " for source '" + ipv6patterns[i] + "' = '" + p + "', ip match = " + p.matches(addr));
104      }
105      catch (Exception e)
106      {
107        System.out.println("#" + i + " : " + e.getMessage());
108      }
109    }
110  }
111}