LinkProperties.java revision 0a46db5d88461d9a6c85bb2e95982ac4c511d57e
147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt/*
26e80997a9a7b6a15370544edde322cd8833e9524Wink Saville * Copyright (C) 2010 The Android Open Source Project
347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt *
447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License");
547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * you may not use this file except in compliance with the License.
647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * You may obtain a copy of the License at
747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt *
847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt *      http://www.apache.org/licenses/LICENSE-2.0
947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt *
1047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * Unless required by applicable law or agreed to in writing, software
1147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS,
1247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * See the License for the specific language governing permissions and
1447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * limitations under the License.
1547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt */
1647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltpackage android.net;
1847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwaltimport android.net.ProxyProperties;
2047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport android.os.Parcelable;
2147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport android.os.Parcel;
224e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wangimport android.text.TextUtils;
2347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
2447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.InetAddress;
2547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.UnknownHostException;
2647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.util.ArrayList;
2747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.util.Collection;
2837e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwaltimport java.util.Collections;
2947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
3047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt/**
3137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt * Describes the properties of a network link.
32992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
33992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * A link represents a connection to a network.
34992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * It may have multiple addresses and multiple gateways,
35992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * multiple dns servers but only one http proxy.
36992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
37992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * Because it's a single network, the dns's
38992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * are interchangeable and don't need associating with
39992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * particular addresses.  The gateways similarly don't
40992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * need associating with particular addresses.
41992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
42992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * A dual stack interface works fine in this model:
43992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * each address has it's own prefix length to describe
44992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * the local network.  The dns servers all return
45992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * both v4 addresses and v6 addresses regardless of the
46992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * address family of the server itself (rfc4213) and we
47992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * don't care which is used.  The gateways will be
48992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * selected based on the destination address and the
49992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * source address has no relavence.
5047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * @hide
5147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt */
5237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwaltpublic class LinkProperties implements Parcelable {
5347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
54ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    String mIfaceName;
55e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private Collection<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
56e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private Collection<InetAddress> mDnses = new ArrayList<InetAddress>();
57e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private Collection<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
5847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    private ProxyProperties mHttpProxy;
5947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
600a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public static class CompareResult<T> {
610a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        public ArrayList<T> removed = new ArrayList<T>();
620a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        public ArrayList<T> added = new ArrayList<T>();
63e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
64e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        @Override
65e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        public String toString() {
660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            String retVal = "removed=[";
670a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (T addr : removed) retVal += addr.toString() + ",";
680a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            retVal += "] added=[";
690a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (T addr : added) retVal += addr.toString() + ",";
70e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            retVal += "]";
71e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            return retVal;
72e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        }
73e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
74e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
7537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public LinkProperties() {
7647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        clear();
7747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
7847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
7937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    // copy constructor instead of clone
8037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public LinkProperties(LinkProperties source) {
81ef6c1431fa2039a4b8c604d651bb8f4dc0806581Irfan Sheriff        if (source != null) {
82ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            mIfaceName = source.getInterfaceName();
83ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            mLinkAddresses = source.getLinkAddresses();
84ef6c1431fa2039a4b8c604d651bb8f4dc0806581Irfan Sheriff            mDnses = source.getDnses();
85aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            mRoutes = source.getRoutes();
86be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville            mHttpProxy = (source.getHttpProxy() == null)  ?
87be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                null : new ProxyProperties(source.getHttpProxy());
88ef6c1431fa2039a4b8c604d651bb8f4dc0806581Irfan Sheriff        }
8937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    }
9037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt
91ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    public void setInterfaceName(String iface) {
92ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        mIfaceName = iface;
9347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
94ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
9537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public String getInterfaceName() {
96ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        return mIfaceName;
9747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
9847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
9937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public Collection<InetAddress> getAddresses() {
100ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        Collection<InetAddress> addresses = new ArrayList<InetAddress>();
101ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        for (LinkAddress linkAddress : mLinkAddresses) {
102ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            addresses.add(linkAddress.getAddress());
103ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        }
104ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        return Collections.unmodifiableCollection(addresses);
105ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    }
106ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
107ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    public void addLinkAddress(LinkAddress address) {
10804cac40ff86e175444991c07869cb85219db1019Robert Greenwalt        if (address != null) mLinkAddresses.add(address);
109ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    }
110ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
111ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    public Collection<LinkAddress> getLinkAddresses() {
112ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        return Collections.unmodifiableCollection(mLinkAddresses);
11347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
11447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
11537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void addDns(InetAddress dns) {
11604cac40ff86e175444991c07869cb85219db1019Robert Greenwalt        if (dns != null) mDnses.add(dns);
11747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
118ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
11937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public Collection<InetAddress> getDnses() {
12037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        return Collections.unmodifiableCollection(mDnses);
12147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
12247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
123aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public void addRoute(RouteInfo route) {
124aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (route != null) mRoutes.add(route);
12547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
126aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public Collection<RouteInfo> getRoutes() {
127aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return Collections.unmodifiableCollection(mRoutes);
12847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
12947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
13037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void setHttpProxy(ProxyProperties proxy) {
13147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        mHttpProxy = proxy;
13247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
13337e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public ProxyProperties getHttpProxy() {
13447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return mHttpProxy;
13547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
13647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
13737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void clear() {
138ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        mIfaceName = null;
139e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mLinkAddresses.clear();
140e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mDnses.clear();
141e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mRoutes.clear();
14247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        mHttpProxy = null;
14347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
14447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
14547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
14647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface
14747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * @hide
14847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
14947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    public int describeContents() {
15047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return 0;
15147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
15247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1531f6408a96c757b3001c553f8f34ef0bda00a224dWink Saville    @Override
15437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public String toString() {
155ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " ");
15647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
157ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        String linkAddresses = "LinkAddresses: [";
1584e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ",";
159ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        linkAddresses += "] ";
16047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
16147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        String dns = "DnsAddresses: [";
1621f6408a96c757b3001c553f8f34ef0bda00a224dWink Saville        for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
16347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dns += "] ";
16447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
165aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        String routes = "Routes: [";
166aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        for (RouteInfo route : mRoutes) routes += route.toString() + ",";
167aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        routes += "] ";
16847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
16947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
170aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return ifaceName + linkAddresses + routes + dns + proxy;
17147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
17247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
173e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
174e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} interface name against the target
175e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
176e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
177e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
178e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
179e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalInterfaceName(LinkProperties target) {
180e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
181e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
182e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
183e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
184e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} interface name against the target
185e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
186e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
187e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
188e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
189e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalAddresses(LinkProperties target) {
190e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<InetAddress> targetAddresses = target.getAddresses();
191e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<InetAddress> sourceAddresses = getAddresses();
192e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (sourceAddresses.size() == targetAddresses.size()) ?
193e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    sourceAddresses.containsAll(targetAddresses) : false;
194e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
195e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
196e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
197e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} DNS addresses against the target
198e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
199e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
200e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
201e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
202e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalDnses(LinkProperties target) {
203e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<InetAddress> targetDnses = target.getDnses();
204e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (mDnses.size() == targetDnses.size()) ?
205e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    mDnses.containsAll(targetDnses) : false;
206e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
207e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
208e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
209e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} Routes against the target
210e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
211e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
212e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
213e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
214e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalRoutes(LinkProperties target) {
215e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<RouteInfo> targetRoutes = target.getRoutes();
216e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (mRoutes.size() == targetRoutes.size()) ?
217e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    mRoutes.containsAll(targetRoutes) : false;
218e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
219e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
220e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
221e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} HttpProxy against the target
222e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
223e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
224e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
225e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
226e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalHttpProxy(LinkProperties target) {
227e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return getHttpProxy() == null ? target.getHttpProxy() == null :
228e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    getHttpProxy().equals(target.getHttpProxy());
229e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
2304e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
2314e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    @Override
2324e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    /**
2334e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * Compares this {@code LinkProperties} instance against the target
2344e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
2354e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * all their fields are equal in values.
2364e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     *
2374e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * For collection fields, such as mDnses, containsAll() is used to check
2384e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * if two collections contains the same elements, independent of order.
2394e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * There are two thoughts regarding containsAll()
2404e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
2414e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * 2. Worst case performance is O(n^2).
2424e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     *
2434e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * @param obj the object to be tested for equality.
2444e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * @return {@code true} if both objects are equal, {@code false} otherwise.
2454e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     */
2464e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    public boolean equals(Object obj) {
2474e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        if (this == obj) return true;
2484e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
2494e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        if (!(obj instanceof LinkProperties)) return false;
2504e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
2514e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        LinkProperties target = (LinkProperties) obj;
2524e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
253e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return isIdenticalInterfaceName(target) &&
254e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalAddresses(target) &&
255e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalDnses(target) &&
256e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalRoutes(target) &&
257e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalHttpProxy(target);
258e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
2594e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
260e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
261e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Return two lists, a list of addresses that would be removed from
262e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * mLinkAddresses and a list of addresses that would be added to
263e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * mLinkAddress which would then result in target and mLinkAddresses
264e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * being the same list.
265e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
2660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * @param target is a LinkProperties with the new list of addresses
267e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return the removed and added lists.
268e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
2690a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
270e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        /*
271e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * Duplicate the LinkAddresses into removed, we will be removing
272e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * address which are common between mLinkAddresses and target
273e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * leaving the addresses that are different. And address which
274e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * are in target but not in mLinkAddresses are placed in the
275e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * addedAddresses.
276e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         */
2770a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<LinkAddress> result = new CompareResult<LinkAddress>();
278e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
279e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        result.added.clear();
2800a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
2810a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (LinkAddress newAddress : target.getLinkAddresses()) {
2820a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(newAddress)) {
2830a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(newAddress);
2840a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
285e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
286e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        }
287e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return result;
2884e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    }
2894e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
2900a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
2910a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * Return two lists, a list of dns addresses that would be removed from
2920a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * mDnses and a list of addresses that would be added to
2930a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * mDnses which would then result in target and mDnses
2940a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * being the same list.
2950a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     *
2960a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * @param target is a LinkProperties with the new list of dns addresses
2970a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * @return the removed and added lists.
2980a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
2990a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public CompareResult<InetAddress> compareDnses(LinkProperties target) {
3000a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        /*
3010a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * Duplicate the InetAddresses into removed, we will be removing
3020a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * dns address which are common between mDnses and target
3030a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * leaving the addresses that are different. And dns address which
3040a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * are in target but not in mDnses are placed in the
3050a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * addedAddresses.
3060a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         */
3070a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<InetAddress> result = new CompareResult<InetAddress>();
3080a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
3090a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.removed = new ArrayList<InetAddress>(mDnses);
3100a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.added.clear();
3110a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
3120a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (InetAddress newAddress : target.getDnses()) {
3130a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(newAddress)) {
3140a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(newAddress);
3150a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
3160a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
3170a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        }
3180a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return result;
3190a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
3200a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
3210a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
3220a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * Return two lists, a list of routes that would be removed from
3230a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * mRoutes and a list of routes that would be added to
3240a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * mRoutes which would then result in target and mRoutes
3250a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * being the same list.
3260a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     *
3270a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * @param target is a LinkProperties with the new list of routes
3280a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * @return the removed and added lists.
3290a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
3300a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public CompareResult<RouteInfo> compareRoutes(LinkProperties target) {
3310a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        /*
3320a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * Duplicate the RouteInfos into removed, we will be removing
3330a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * routes which are common between mDnses and target
3340a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * leaving the routes that are different. And route address which
3350a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * are in target but not in mRoutes are placed in added.
3360a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         */
3370a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();
3380a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
3390a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.removed = new ArrayList<RouteInfo>(mRoutes);
3400a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.added.clear();
3410a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
3420a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (RouteInfo r : target.getRoutes()) {
3430a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(r)) {
3440a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(r);
3450a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
3460a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
3470a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        }
3480a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return result;
3490a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
3500a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
3510a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
3524e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    @Override
3534e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    /**
3544e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * generate hashcode based on significant fields
3554e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * Equal objects must produce the same hash code, while unequal objects
3564e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * may have the same hash codes.
3574e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     */
3584e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    public int hashCode() {
3594e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
3604e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang                + mLinkAddresses.size() * 31
3614e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang                + mDnses.size() * 37
362aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                + mRoutes.size() * 41
3634e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang                + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode()));
3644e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    }
3654e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
36647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
36747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface.
36847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * @hide
36947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
37037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void writeToParcel(Parcel dest, int flags) {
37147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dest.writeString(getInterfaceName());
372ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        dest.writeInt(mLinkAddresses.size());
373ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        for(LinkAddress linkAddress : mLinkAddresses) {
374ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            dest.writeParcelable(linkAddress, flags);
37547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
376ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
37747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dest.writeInt(mDnses.size());
37847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        for(InetAddress d : mDnses) {
37947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByteArray(d.getAddress());
38047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
381992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt
382aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        dest.writeInt(mRoutes.size());
383aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        for(RouteInfo route : mRoutes) {
384aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeParcelable(route, flags);
38547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
386992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt
38747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        if (mHttpProxy != null) {
38847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByte((byte)1);
38947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeParcelable(mHttpProxy, flags);
39047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        } else {
39147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByte((byte)0);
39247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
39347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
39447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
39547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
39647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface.
39747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * @hide
39847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
39937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public static final Creator<LinkProperties> CREATOR =
40037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        new Creator<LinkProperties>() {
40137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            public LinkProperties createFromParcel(Parcel in) {
40237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                LinkProperties netProp = new LinkProperties();
40347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                String iface = in.readString();
40447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (iface != null) {
40547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    try {
406ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff                        netProp.setInterfaceName(iface);
40747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    } catch (Exception e) {
40847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                        return null;
40947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    }
41047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
41147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                int addressCount = in.readInt();
41247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                for (int i=0; i<addressCount; i++) {
413ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff                    netProp.addLinkAddress((LinkAddress)in.readParcelable(null));
41447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
41547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                addressCount = in.readInt();
41647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                for (int i=0; i<addressCount; i++) {
41747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    try {
4181cf56ab9c68334d9124c52bcede06aaa0b17c730Irfan Sheriff                        netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
41947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    } catch (UnknownHostException e) { }
42047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
421992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                addressCount = in.readInt();
422992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                for (int i=0; i<addressCount; i++) {
423aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                    netProp.addRoute((RouteInfo)in.readParcelable(null));
42447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
42547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (in.readByte() == 1) {
42647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    netProp.setHttpProxy((ProxyProperties)in.readParcelable(null));
42747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
42847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                return netProp;
42947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            }
43047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
43137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            public LinkProperties[] newArray(int size) {
43237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                return new LinkProperties[size];
43347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            }
43447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        };
43547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt}
436