aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java454
1 files changed, 454 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java
new file mode 100644
index 00000000..70d6c9ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java
@@ -0,0 +1,454 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Exposes a URL as a Resource.
+ * @since Ant 1.7
+ */
+public class URLResource extends Resource implements URLProvider {
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private static final int NULL_URL
+ = Resource.getMagicNumber("null URL".getBytes());
+
+ private URL url;
+ private URLConnection conn;
+ private URL baseURL;
+ private String relPath;
+
+ /**
+ * Default constructor.
+ */
+ public URLResource() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param u the URL to expose.
+ */
+ public URLResource(URL u) {
+ setURL(u);
+ }
+
+ /**
+ * Convenience constructor.
+ * @param u holds the URL to expose.
+ */
+ public URLResource(URLProvider u) {
+ setURL(u.getURL());
+ }
+
+ /**
+ * Convenience constructor.
+ * @param f the File to set as a URL.
+ */
+ public URLResource(File f) {
+ setFile(f);
+ }
+
+ /**
+ * String constructor for Ant attribute introspection.
+ * @param u String representation of this URL.
+ * @see org.apache.tools.ant.IntrospectionHelper
+ */
+ public URLResource(String u) {
+ this(newURL(u));
+ }
+
+ /**
+ * Set the URL for this URLResource.
+ * @param u the URL to expose.
+ */
+ public synchronized void setURL(URL u) {
+ checkAttributesAllowed();
+ url = u;
+ }
+
+ /**
+ * Set the URL from a File.
+ * @param f the File to set as a URL.
+ */
+ public synchronized void setFile(File f) {
+ try {
+ setURL(FILE_UTILS.getFileURL(f));
+ } catch (MalformedURLException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Base URL which combined with the relativePath attribute defines
+ * the URL.
+ * @since Ant 1.8.0
+ */
+ public synchronized void setBaseURL(URL base) {
+ checkAttributesAllowed();
+ if (url != null) {
+ throw new BuildException("can't define URL and baseURL attribute");
+ }
+ baseURL = base;
+ }
+
+ /**
+ * Relative path which combined with the baseURL attribute defines
+ * the URL.
+ * @since Ant 1.8.0
+ */
+ public synchronized void setRelativePath(String r) {
+ checkAttributesAllowed();
+ if (url != null) {
+ throw new BuildException("can't define URL and relativePath"
+ + " attribute");
+ }
+ relPath = r;
+ }
+
+
+ /**
+ * Get the URL used by this URLResource.
+ * @return a URL object.
+ */
+ public synchronized URL getURL() {
+ if (isReference()) {
+ return ((URLResource) getCheckedRef()).getURL();
+ }
+ if (url == null) {
+ if (baseURL != null) {
+ if (relPath == null) {
+ throw new BuildException("must provide relativePath"
+ + " attribute when using baseURL.");
+ }
+ try {
+ url = new URL(baseURL, relPath);
+ } catch (MalformedURLException e) {
+ throw new BuildException(e);
+ }
+ }
+ }
+ return url;
+ }
+
+ /**
+ * Overrides the super version.
+ * @param r the Reference to set.
+ */
+ public synchronized void setRefid(Reference r) {
+ //not using the accessor in this case to avoid side effects
+ if (url != null || baseURL != null || relPath != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Get the name of this URLResource
+ * (its file component minus the leading separator).
+ * @return the name of this resource.
+ */
+ public synchronized String getName() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getName();
+ }
+ String name = getURL().getFile();
+ return "".equals(name) ? name : name.substring(1);
+ }
+
+ /**
+ * Return this URLResource formatted as a String.
+ * @return a String representation of this URLResource.
+ */
+ public synchronized String toString() {
+ return isReference()
+ ? getCheckedRef().toString() : String.valueOf(getURL());
+ }
+
+ /**
+ * Find out whether the URL exists .
+ * @return true if this resource exists.
+ */
+ public synchronized boolean isExists() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).isExists();
+ }
+ return isExists(false);
+ }
+
+ /**
+ * Find out whether the URL exists, and close the connection
+ * opened to the URL if closeConnection is true.
+ *
+ * Note that this method does ensure that if:
+ * - the resource exists (if it returns true)
+ * - and if the current object is not a reference
+ * (isReference() returns false)
+ * - and if it was called with closeConnection to false,
+ *
+ * then the connection to the URL (stored in the conn
+ * private field) will be opened, and require to be closed
+ * by the caller.
+ *
+ * @param closeConnection true if the connection should be closed
+ * after the call, false if it should stay open.
+ * @return true if this resource exists.
+ */
+ private synchronized boolean isExists(boolean closeConnection) {
+ if (getURL() == null) {
+ return false;
+ }
+ try {
+ connect(Project.MSG_VERBOSE);
+ if (conn instanceof HttpURLConnection) {
+ int sc = ((HttpURLConnection) conn).getResponseCode();
+ // treating inaccessible resources as non-existent
+ return sc < 400;
+ } else if (url.getProtocol().startsWith("ftp")) {
+ closeConnection = true;
+ InputStream in = null;
+ try {
+ in = conn.getInputStream();
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+ return true;
+ } catch (IOException e) {
+ return false;
+ } finally {
+ if (closeConnection) {
+ close();
+ }
+ }
+ }
+
+
+ /**
+ * Tells the modification time in milliseconds since 01.01.1970 .
+ *
+ * @return 0 if the resource does not exist to mirror the behavior
+ * of {@link java.io.File File}.
+ */
+ public synchronized long getLastModified() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getLastModified();
+ }
+ if (!isExists(false)) {
+ return UNKNOWN_DATETIME;
+ }
+ return withConnection(new ConnectionUser() {
+ public long useConnection(URLConnection c) {
+ return conn.getLastModified();
+ }
+ }, UNKNOWN_DATETIME);
+ }
+
+ /**
+ * Tells if the resource is a directory.
+ * @return boolean whether the resource is a directory.
+ */
+ public synchronized boolean isDirectory() {
+ return isReference()
+ ? ((Resource) getCheckedRef()).isDirectory()
+ : getName().endsWith("/");
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist (for
+ * compatibility with java.io.File), or UNKNOWN_SIZE if not known.
+ */
+ public synchronized long getSize() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getSize();
+ }
+ if (!isExists(false)) {
+ return 0L;
+ }
+ return withConnection(new ConnectionUser() {
+ public long useConnection(URLConnection c) {
+ return conn.getContentLength();
+ }
+ }, UNKNOWN_SIZE);
+ }
+
+ /**
+ * Test whether an Object equals this URLResource.
+ * @param another the other Object to compare.
+ * @return true if the specified Object is equal to this Resource.
+ */
+ public synchronized boolean equals(Object another) {
+ if (this == another) {
+ return true;
+ }
+ if (isReference()) {
+ return getCheckedRef().equals(another);
+ }
+ if (another == null || !(another.getClass().equals(getClass()))) {
+ return false;
+ }
+ URLResource otheru = (URLResource) another;
+ return getURL() == null
+ ? otheru.getURL() == null
+ : getURL().equals(otheru.getURL());
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @return hash code as int.
+ */
+ public synchronized int hashCode() {
+ if (isReference()) {
+ return getCheckedRef().hashCode();
+ }
+ return MAGIC * ((getURL() == null) ? NULL_URL : getURL().hashCode());
+ }
+
+ /**
+ * Get an InputStream for the Resource.
+ * @return an InputStream containing this Resource's content.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if InputStreams are not
+ * supported for this Resource type.
+ */
+ public synchronized InputStream getInputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getInputStream();
+ }
+ connect();
+ try {
+ return conn.getInputStream();
+ } finally {
+ conn = null;
+ }
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ * @throws IOException if the URL cannot be opened.
+ */
+ public synchronized OutputStream getOutputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getOutputStream();
+ }
+ connect();
+ try {
+ return conn.getOutputStream();
+ } finally {
+ conn = null;
+ }
+ }
+
+ /**
+ * Ensure that we have a connection.
+ * @throws IOException if the connection cannot be established.
+ */
+ protected void connect() throws IOException {
+ connect(Project.MSG_ERR);
+ }
+
+ /**
+ * Ensure that we have a connection.
+ * @param logLevel severity to use when logging connection errors.
+ * Should be one of the <code>MSG_</code> constants in {@link
+ * Project Project}.
+ * @throws IOException if the connection cannot be established.
+ * @since Ant 1.8.2
+ */
+ protected synchronized void connect(int logLevel) throws IOException {
+ URL u = getURL();
+ if (u == null) {
+ throw new BuildException("URL not set");
+ }
+ if (conn == null) {
+ try {
+ conn = u.openConnection();
+ conn.connect();
+ } catch (IOException e) {
+ log(e.toString(), logLevel);
+ conn = null;
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * Closes the URL connection if:
+ * - it is opened (i.e. the field conn is not null)
+ * - this type of URLConnection supports some sort of close mechanism
+ *
+ * This method ensures the field conn will be null after the call.
+ *
+ */
+ private synchronized void close() {
+ try {
+ FileUtils.close(conn);
+ } finally {
+ conn = null;
+ }
+ }
+
+ private static URL newURL(String u) {
+ try {
+ return new URL(u);
+ } catch (MalformedURLException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ private interface ConnectionUser {
+ long useConnection(URLConnection c);
+ }
+
+ private long withConnection(ConnectionUser u, long defaultValue) {
+ try {
+ if (conn != null) {
+ return u.useConnection(conn);
+ } else {
+ try {
+ connect();
+ return u.useConnection(conn);
+ } finally {
+ close();
+ }
+ }
+ } catch (IOException ex) {
+ return defaultValue;
+ }
+ }
+}