/** * * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * **/ package lucee.runtime.net.ipsettings; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class IPRangeCollection { private List<IPRangeNode> list = Collections.EMPTY_LIST; void add( IPRangeNode child, boolean doCheck ) { if ( list == Collections.EMPTY_LIST ) list = new ArrayList(); else if ( doCheck ) { // scan for previous children in parent that should be moved under the newly added child after this addition int listSize = list.size(); for ( int i=0; i < listSize; i++ ) { IPRangeNode sibling = list.get(i); if ( child.containsRange( sibling ) ) { // move sibling under new child list.remove(i--); // adjust i and numChildren due to removal listSize--; child.addChild( sibling ); } } } list.add( child ); } public void add( IPRangeNode child ) { this.add( child, true ); } public IPRangeNode findFast( InetAddress iaddr, List<IPRangeNode> parents ) { IPRangeNode needle, parent; needle = new IPRangeNode( iaddr, iaddr ); int pos = Collections.binarySearch( list, needle, IPRangeNode.comparerRange ); if ( pos > -1 ) { parent = list.get(pos); return parent.findFast(iaddr, parents); } int tests = 2; pos = Math.abs(pos); pos = Math.max(0, pos - tests); int max = Math.min( pos + tests, list.size() ); for (; pos < max; pos++ ) { if ( list.get( pos ).isInRange( iaddr ) ) { parent = list.get( pos ); return parent.findFast(iaddr, parents); } } return null; } /** * performs a binary search over a sorted list * * @param iaddr * @return */ public IPRangeNode findFast( InetAddress iaddr ) { IPRangeNode needle, parent; needle = new IPRangeNode( iaddr, iaddr ); int pos = Collections.binarySearch( list, needle, IPRangeNode.comparerRange ); if ( pos > -1 ) { parent = list.get(pos); return parent.findFast(iaddr); } int tests = 2; pos = Math.abs(pos); pos = Math.max(0, pos - tests); int max = Math.min( pos + tests, list.size() ); for (; pos < max; pos++ ) { if ( list.get( pos ).isInRange( iaddr ) ) { parent = list.get( pos ); return parent.findFast(iaddr); } } return null; } /** * performs a binary search over sorted list * * @param addr * @return */ public IPRangeNode findFast( String addr ) { InetAddress iaddr; try { iaddr = InetAddress.getByName(addr); } catch (UnknownHostException ex) { return null; } return findFast( iaddr ); } /** * performs a linear scan for unsorted lists * * @param addr * @return */ public IPRangeNode findAddr( InetAddress addr ) { for ( IPRangeNode c : this.list ) { IPRangeNode result = c.findAddr( addr ); if ( result != null ) return result; } return null; } /** * performs a linear scan for unsorted lists * * @param child * @return */ public IPRangeNode findRange( IPRangeNode child ) { for ( IPRangeNode c : this.list ) { IPRangeNode result = c.findRange( child ); if ( result != null ) return result; } return null; } public int size() { return list.size(); } private void sort() { Collections.sort( this.list ); } public void sortChildren() { for ( IPRangeNode node : this.list ) { node.getChildren().sort(); } } }