/** * <copyright> * * Copyright (c) 2004, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM - Initial API and implementation * * </copyright> * * $Id$ */ package net.enilink.komma.common.archive; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; /** * A URL stream handler that can be {@link #register() registered} to support * archive access protocol. It uses {@link ArchiveURLConnection} to implement * the connection. */ public class Handler extends URLStreamHandler { /** * Registers this class. A handler for protocol "xyz" is registered by * providing a class named Handler implementing {@link URLStreamHandler} in * a package called named xyz in a package of your choosing, and then * registering that chosen prefix package name in the system property for * <code>"java.protocol.handler.pkgs"</code>, which is an "|" separated list * of package prefixes to search for handlers. */ public static void register() { String javaProtocolHandlerPkgs = System .getProperty("java.protocol.handler.pkgs"); if (javaProtocolHandlerPkgs == null || javaProtocolHandlerPkgs.length() == 0) { javaProtocolHandlerPkgs = "org.eclipse.emf.common"; } else { javaProtocolHandlerPkgs += "|org.eclipse.emf.common"; } System.setProperty("java.protocol.handler.pkgs", javaProtocolHandlerPkgs); } /** * Registers this handler and interprets each argument as URL to be opened, * read in, and written out to System.out. * * @param args * URLs to open, read, and write to System.out * @throws IOException * if there are problems opening or reading from the URLs, or * writing to System.out. */ public static void main(String[] args) throws IOException { register(); for (int i = 0; i < args.length; ++i) { InputStream inputStream = new URL(args[i]).openStream(); byte[] bytes = new byte[4048]; for (int size; (size = inputStream.read(bytes, 0, bytes.length)) > -1;) { System.out.write(bytes, 0, size); } } } /** * Creates an instance. */ public Handler() { super(); } /** * Overrides parsing the URL to validate constraints on well formed archive * syntax. * * @see URLStreamHandler#parseURL(java.net.URL, java.lang.String, int, int) */ @Override protected void parseURL(URL url, String specification, int start, int limit) { super.parseURL(url, specification, start, limit); // There needs to be another URL protocol right after the archive // protocol, and not a "/". // if (start > limit || specification.charAt(start) == '/') { throw new IllegalArgumentException( "archive protocol must be immediately followed by another URL protocol " + specification); } // There must be at least one archive path. // int archiveSeparator = specification.indexOf("!/", start); if (archiveSeparator < 0) { throw new IllegalArgumentException("missing archive separators " + specification.substring(start, limit)); } // Parse to count the archive paths that must will be delegated to the // nested URL based on the number of schemes at the start. // for (int i = start, end = specification.indexOf('/', start) - 1; (i = specification .indexOf(':', i)) < end; ++i) { // There should be at least one archive separator per scheme. // archiveSeparator = specification .indexOf("!/", archiveSeparator + 2); if (archiveSeparator < 0) { throw new IllegalArgumentException( "too few archive separators " + specification); } } } /** * Returns a new {@link ArchiveURLConnection}. */ @Override protected URLConnection openConnection(URL url) throws IOException { return new ArchiveURLConnection(url); } }