001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU General
007: * Public License Version 2 only ("GPL") or the Common Development and Distribution
008: * License("CDDL") (collectively, the "License"). You may not use this file except in
009: * compliance with the License. You can obtain a copy of the License at
010: * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
011: * License for the specific language governing permissions and limitations under the
012: * License. When distributing the software, include this License Header Notice in
013: * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun
014: * designates this particular file as subject to the "Classpath" exception as
015: * provided by Sun in the GPL Version 2 section of the License file that
016: * accompanied this code. If applicable, add the following below the License Header,
017: * with the fields enclosed by brackets [] replaced by your own identifying
018: * information: "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Contributor(s):
021: *
022: * The Original Software is NetBeans. The Initial Developer of the Original Software
023: * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
024: * Rights Reserved.
025: *
026: * If you wish your version of this file to be governed by only the CDDL or only the
027: * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
028: * this software in this distribution under the [CDDL or GPL Version 2] license." If
029: * you do not indicate a single choice of license, a recipient has the option to
030: * distribute your version of this file under either the CDDL, the GPL Version 2 or
031: * to extend the choice of license to its licensees as provided above. However, if
032: * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
033: * the option applies only if the new code is made subject to such option by the
034: * copyright holder.
035: */
036:
037: package org.netbeans.installer.sandbox.download.proxy;
038:
039: import org.netbeans.installer.utils.helper.ErrorLevel;
040: import org.netbeans.installer.utils.ResourceUtils;
041: import org.netbeans.installer.utils.ErrorManager;
042: import org.netbeans.installer.utils.LogManager;
043:
044: /**
045: * A representation of a proxy. Connections are expected to use proxies registered
046: * in DownloadManager to alter their way to connect to remote machines (if
047: * supported/requried). Unlike the standard <code>java.net.Proxy</code>, this class
048: * provides support for encapsulating the required username/password credentials as
049: * well as the list of hosts for which this proxy should be bypassed.
050: *
051: * @author Kirill Sorokin
052: */
053: public class Proxy {
054: /////////////////////////////////////////////////////////////////////////////////
055: // Constants
056: /**
057: * The symbol with which the host names are separated in the string list of
058: * hosts for which the proxy should be bypassed.
059: */
060: private static final String NON_PROXY_HOSTS_SEPARATOR = "\\|"; // NOI18N
061:
062: /**
063: * Resource bundle key name - the name of the SOCKS proxy type.
064: */
065: private static final String KEY_TYPE_SOCKS = "Proxy.ProxyType.socks"; // NOI18N
066:
067: /**
068: * Resource bundle key name - the name of the HTTP proxy type.
069: */
070: private static final String KEY_TYPE_HTTP = "Proxy.ProxyType.http"; // NOI18N
071:
072: /**
073: * Resource bundle key name - the name of the HTTPS proxy type.
074: */
075: private static final String KEY_TYPE_HTTPS = "Proxy.ProxyType.https"; // NOI18N
076:
077: /**
078: * Resource bundle key name - the name of the FTP proxy type.
079: */
080: private static final String KEY_TYPE_FTP = "Proxy.ProxyType.ftp"; // NOI18N
081:
082: /**
083: * Resource bundle key name - warning message yelded when the port of a
084: * proxy cannot be parsed.
085: */
086: private static final String KEY_CANNOT_PARSE_PORT = "Proxy.warning.cannotParsePort"; // NOI18N
087:
088: /**
089: * Resource bundle key name - warning message yelded when either the host or the
090: * port of a proxy is null (i.e. is not set).
091: */
092: private static final String KEY_NULL_HOST_OR_PORT = "Proxy.warning.nullHostOrPort"; // NOI18N
093:
094: /////////////////////////////////////////////////////////////////////////////////
095: // Static
096: /**
097: * Constructs a <code>Proxy</code> using the values of the supplied system
098: * properties. It is used in the <code>DownloadManager</code> to register all the
099: * proxies defined by the system (useful when the application is started via JNLP
100: * or an applet.
101: *
102: * @param type The type of proxy to be constructed.
103: * @param hostProperty The name of the system property which holds the proxy
104: * host.
105: * @param portProperty The name of the system property which holds the proxy
106: * port.
107: * @param nonProxyHostsProperty The name of the system property which holds the
108: * list of hosts for which the proxy should be bypassed.
109: * @return The constructed <code>Proxy</code> or <code>null</code> if something
110: * did not allow to parse the data correctly.
111: */
112: public static Proxy parseProxy(ProxyType type, String hostProperty,
113: String portProperty, String nonProxyHostsProperty) {
114: String host = System.getProperty(hostProperty);
115: String port = System.getProperty(portProperty);
116:
117: // if either the host or the port are null (i.e. not set), it does not make
118: // any sense to continue parsing - issue a warning
119: if ((host != null) && (port != null)) {
120: try {
121: String nonProxyHosts = System
122: .getProperty(nonProxyHostsProperty);
123: String[] nonProxyHostsArray;
124: if (nonProxyHosts != null) {
125: nonProxyHostsArray = nonProxyHosts
126: .split(NON_PROXY_HOSTS_SEPARATOR);
127: } else {
128: nonProxyHostsArray = new String[0];
129: }
130:
131: int intPort = Integer.parseInt(port);
132:
133: nonProxyHosts = "";
134: for (int i = 0; i < nonProxyHostsArray.length; i++) {
135: nonProxyHostsArray[i] = nonProxyHostsArray[i]
136: .replace(".", "\\.").replace("*", ".*");
137:
138: nonProxyHosts += nonProxyHostsArray[i];
139: if (i != nonProxyHostsArray.length - 1) {
140: nonProxyHosts += ", ";
141: }
142: }
143:
144: LogManager.log(ErrorLevel.WARNING,
145: " ... proxy successfully parsed -- "
146: + host + ":" + port + ", exceptions: "
147: + nonProxyHosts);
148:
149: return new Proxy(type, host, intPort,
150: nonProxyHostsArray);
151: } catch (NumberFormatException e) {
152: LogManager.log(ErrorLevel.WARNING,
153: " ... cannot parse the port ("
154: + portProperty + " = " + port
155: + ") of the supplied system proxy");
156: }
157: } else {
158: LogManager
159: .log(
160: ErrorLevel.WARNING,
161: " ... either the host ("
162: + hostProperty
163: + ") or the port ("
164: + portProperty
165: + ") of the supplied system proxy were not defined");
166: }
167:
168: return null;
169: }
170:
171: /////////////////////////////////////////////////////////////////////////////////
172: // Instance
173: /**
174: * The type of this proxy.
175: */
176: private ProxyType myType;
177:
178: /**
179: * The host of this proxy.
180: */
181: private String myHost;
182:
183: /**
184: * The port of this proxy.
185: */
186: private int myPort;
187:
188: /**
189: * The username which should be used to authenticate with this proxy.
190: */
191: private String myUsername;
192:
193: /**
194: * The password which should be used to authenticate with this proxy.
195: */
196: private String myPassword;
197:
198: /**
199: * The list of hosts for which this proxy should be bypassed. Each entry can be a
200: * RE pattern, to facilitate describing a group of hosts.
201: */
202: private String[] myNonProxyHosts;
203:
204: /**
205: * Constructs a new instance of <code>Proxy</code>. The username, password and
206: * the list of hosts for which to bypass this proxy are set to null, null and
207: * an empty array correspondingly.
208: *
209: * @param type The type of this proxy.
210: * @param host The host of this proxy.
211: * @param port The port of this proxy.
212: */
213: public Proxy(ProxyType type, String host, int port) {
214: myType = type;
215:
216: myHost = host;
217: myPort = port;
218:
219: myUsername = null;
220: myPassword = null;
221:
222: myNonProxyHosts = new String[0];
223: }
224:
225: /**
226: * Constructs a new instance of <code>Proxy</code>. The username and password
227: * are set to null.
228: *
229: * @param type The type of this proxy.
230: * @param host The host of this proxy.
231: * @param port The port of this proxy.
232: * @param nonProxyHosts The list of hosts for which this proxy should be
233: * bypassed.
234: */
235: public Proxy(ProxyType type, String host, int port,
236: String[] nonProxyHosts) {
237: this (type, host, port);
238:
239: myNonProxyHosts = nonProxyHosts;
240: }
241:
242: /**
243: * Constructs a new instance of <code>Proxy</code>.
244: *
245: * @param type The type of this proxy.
246: * @param host The host of this proxy.
247: * @param port The port of this proxy.
248: * @param username The username to be used to authenticate with this proxy.
249: * @param password The password to be used to authenticate with this proxy.
250: * @param nonProxyHosts The list of hosts for which this proxy should be
251: * bypassed.
252: */
253: public Proxy(ProxyType type, String host, int port,
254: String username, String password, String[] nonProxyHosts) {
255: this (type, host, port, nonProxyHosts);
256:
257: myUsername = username;
258: myPassword = password;
259: }
260:
261: /**
262: * Getter for the <code>myType</code> property.
263: *
264: * @return The type of this proxy.
265: */
266: public ProxyType getType() {
267: return myType;
268: }
269:
270: /**
271: * Getter for the <code>myHost</code> property.
272: *
273: * @return The host of this proxy.
274: */
275: public String getHost() {
276: return myHost;
277: }
278:
279: /**
280: * Getter for the <code>myPort</code> property.
281: *
282: * @return The port of this proxy.
283: */
284: public int getPort() {
285: return myPort;
286: }
287:
288: /**
289: * Getter for the <code>myUsername</code> property.
290: *
291: * @return The username to be used to authenticate with this proxy.
292: */
293: public String getUsername() {
294: return myUsername;
295: }
296:
297: /**
298: * Getter for the <code>myPassword</code> property.
299: *
300: * @return The password to be used to authenticate with this proxy.
301: */
302: public String getPassword() {
303: return myPassword;
304: }
305:
306: /**
307: * Getter for the <code>myNonProxyHosts</code> property.
308: *
309: * @return The list of hosts for which this proxy should be bypassed.
310: */
311: public String[] getNonProxyHosts() {
312: return myNonProxyHosts;
313: }
314:
315: /**
316: * Checks whether the given host should be reached via the proxy or the proxy
317: * should be bypassed.
318: *
319: * @param host The host to check.
320: * @return <code>true</code> is the proxy should be bypassed, <code>false</code>
321: * otherwise.
322: */
323: public boolean skipProxyForHost(String host) {
324: for (String pattern : myNonProxyHosts) {
325: if (host.matches(pattern)) {
326: return true;
327: }
328: }
329:
330: return false;
331: }
332:
333: /////////////////////////////////////////////////////////////////////////////////
334: // Inner Classes
335: /**
336: * An enumeration depicting all possible proxy types. Currently four types are
337: * supported: SOCKS, HTTP, HTTPS, FTP.
338: *
339: * @author Kirill Sorokin
340: */
341: public static enum ProxyType {
342: SOCKS(ResourceUtils.getString(Proxy.class, KEY_TYPE_SOCKS)), HTTP(
343: ResourceUtils.getString(Proxy.class, KEY_TYPE_HTTP)), HTTPS(
344: ResourceUtils.getString(Proxy.class, KEY_TYPE_HTTPS)), FTP(
345: ResourceUtils.getString(Proxy.class, KEY_TYPE_FTP));
346:
347: /**
348: * The string representation of this proxy type.
349: */
350: private String myName;
351:
352: /**
353: * Constructs a new <code>ProxyType</code> with the given type name. The
354: * constructor is obviously private.
355: *
356: * @param name The string representation of this type.
357: */
358: private ProxyType(String name) {
359: myName = name;
360: }
361:
362: /**
363: * {@inheritDoc}
364: */
365: public String toString() {
366: return myName;
367: }
368: }
369: }
|