Package org.jdesktop.wonderland.common

Source Code of org.jdesktop.wonderland.common.ModuleURI

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.common;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;

/**
* The ModuleURI class uniquely identifies a resource within the sytem that is
* managed by the client-side asset management system. The format of a resource
* URI is:
* <p>
* <protocol>://<module name>@<server name>:<port>/<asset path>
* <p>
* where <protocol> refers to the specific kind of asset (e.g. 'wla' for art
* assets, 'wlj' for plugin assets), <module name> is the name of the module
* where the asset lives, and <server name>:<port> is the server name from
* which the asset comes, and <asset path> is the relative path of the asset
* in the module.
*
* @author Jordan Slott <jslott@dev.java.net>
*/
@ExperimentalAPI
public abstract class ModuleURI extends AssetURI {
    private String protocol = null;
    private String moduleName = null;
    private String hostName = null;
    private int hostPort = -1;
    private String assetPath = null;

    /** Default constructor */
    public ModuleURI() {
        super();
    }

    /**
     * Constructor which takes the string represents of the URI.
     *
     * @param uri The string URI representation
     * @throw URISyntaxException If the URI is not well-formed
     */
    public ModuleURI(String uri) throws URISyntaxException {
        super(uri);
        parseURI(uri);
    }

    /**
     * Constructor, takes the components of the URI: protocol, module name,
     * server name, port, and asset path
     */
    public ModuleURI(String protocol, String moduleName, String hostName, int hostPort, String assetPath) {
        super(toURI(protocol, moduleName, hostName, hostPort, assetPath));
        this.protocol = protocol;
        this.moduleName = moduleName;
        this.hostName = hostName;
        this.hostPort = hostPort;
        this.assetPath = assetPath;
    }

    /**
     * Construct, takes the components of the URI: protocol, module name, host
     * name and port, and asset path. The host name and port is given as:
     * <host name>:<port>
     */
    public ModuleURI(String protocol, String moduleName, String hostNameAndPort, String assetPath) {
        super(toURI(protocol, moduleName, hostNameAndPort, assetPath));
        this.protocol = protocol;
        this.moduleName = moduleName;
        this.assetPath = assetPath;
        parseHostNameAndPort(hostNameAndPort);
    }

    /**
     * Returns a URL from the URI.
     *
     * @return A URL
     */
    public URL toURL() throws MalformedURLException {
        return new URL(this.toString());
    }

    /**
     * Returns the module name off this URI.
     *
     * @return The module name
     */
    public String getModuleName() {
        return moduleName;
    }

    /**
     * Returns the raw relative path of the asset, without prepending any
     * assumed directory like "art/". It has no leading "/". This method
     * should return all forward-slashes.
     */
    public String getAssetPath() {
        return assetPath;
    }

    /**
     * Returns the protocol of the URI
     */
    @Override
    public String getProtocol() {
        return protocol;
    }

    /**
     * Returns the host port, -1 if none is set.
     *
     * @return The host port
     */
    public int getHostPort() {
        return hostPort;
    }

    /**
     * Returns the host name, null if none is set.
     *
     * @return The host name
     */
    public String getHostName() {
        return hostName;
    }

    /**
     * Returns the base URL of the server as a string, or null if not present
     *
     * @return The base server URL
     */
    public String getServerURL() {
        /*
         * If a host:port is present, then host is non-null. Otherwise, if
         * user info is null, the only the module name is present and there is
         * no host name
         */
        if (hostName == null) {
            return null;
        }

        String url = "http://" + hostName;
        if (hostPort != -1) {
            url = url + ":" + hostPort;
        }
        return url;
    }

    /**
     * @inheritDoc()
     */
    public void setServerHostAndPort(String hostNameAndPort) {
        parseHostNameAndPort(hostNameAndPort);
    }

    /**
     * Must override toString() to not equal toExternalForm(). In this case,
     * toString() will return the URI with the host name and port for display
     * purposes.
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(protocol + "://" + moduleName);
        if (hostName != null) {
            sb.append("@" + hostName);
            if (hostPort != -1) {
                sb.append(":" + hostPort);
            }
        }
        sb.append("/" + assetPath);
        return sb.toString();
    }

    /**
     * Must override toExternalForm() to not include the host name and port.
     * This method is used to generate a string representation to use in the
     * asset cache. In the case of federation, even if the host name and
     * port differ, they are considered the same for asset purposes.
     */
    @Override
    public String toExternalForm() {
        return protocol + "://" + moduleName + "/" + assetPath;
    }

    /**
     * Returns the URI given the components: protocol, module name, host name,
     * host port, and asset path.
     */
    private static String toURI(String protocol, String moduleName, String hostName, int hostPort, String assetPath) {
        StringBuilder sb = new StringBuilder(protocol + "://" + moduleName);
        if (hostName != null) {
            sb.append("@" + hostName);
            if (hostPort != -1) {
                sb.append(":" + hostPort);
            }
        }
        sb.append("/" + assetPath);
        return sb.toString();
    }

    /**
     * Returns the URI given the components: protocol, module name, host name
     * and port, and asset path.
     */
    private static String toURI(String protocol, String moduleName, String hostNameAndPort, String assetPath) {
        StringBuilder sb = new StringBuilder(protocol + "://" + moduleName);
        if (hostNameAndPort != null) {
            sb.append("@" + hostNameAndPort);
        }
        sb.append("/" + assetPath);
        return sb.toString();
    }

    /**
     * Must Override equals() here -- a module URI is consider equal even if
     * its host and port differ. In the case of federation, even if the same
     * uri has different host name and ports, they are considered the same if
     * all other attributes are equal.
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ModuleURI other = (ModuleURI) obj;
        if (this.protocol != other.protocol && (this.protocol == null || !this.protocol.equals(other.protocol))) {
            return false;
        }
        if (this.moduleName != other.moduleName && (this.moduleName == null || !this.moduleName.equals(other.moduleName))) {
            return false;
        }
        if (this.assetPath != other.assetPath && (this.assetPath == null || !this.assetPath.equals(other.assetPath))) {
            return false;
        }
        return true;
    }

    /**
     * Must override hasCode() here -- the computation should not include the
     * host name and port.
     */
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 47 * hash + (this.protocol != null ? this.protocol.hashCode() : 0);
        hash = 47 * hash + (this.moduleName != null ? this.moduleName.hashCode() : 0);
        hash = 47 * hash + (this.assetPath != null ? this.assetPath.hashCode() : 0);
        return hash;
    }

    /**
     * Parses the string representation of the URI into its component parts.
     */
    private void parseURI(String uri) throws URISyntaxException {
        /* If the uri is null, throw an Exception */
        if (uri == null) {
            throw new URISyntaxException(uri, "URI is NULL");
        }

        /* First check whether the uri contains a <protocol>:// */
        int protocolIndex = uri.indexOf("://");
        if (protocolIndex == -1 || protocolIndex == 0) {
            throw new URISyntaxException(uri, "URI does not contain a protocol");
        }
        protocol = uri.substring(0, protocolIndex);

        /* Advance the index to after the "://" */
        protocolIndex += 3;

        /*
         * Next parse out the module name. If we find a "@" first, then there
         * is also a hostname. If we find a "/" next, then there is no host name
         */
        int atIndex = uri.indexOf("@", protocolIndex);
        int slashIndex = uri.indexOf("/", protocolIndex);
        if (atIndex != -1 && atIndex < slashIndex) {
            moduleName = uri.substring(protocolIndex, atIndex);
        }
        else if (slashIndex != -1) {
            moduleName = uri.substring(protocolIndex, slashIndex);
        }
        else {
            throw new URISyntaxException(uri, "Cannot find module name in URI");
        }

        /*
         * Next parse out the host name and port if there is one.
         */
        if (atIndex != -1 && atIndex < slashIndex) {
            int colonIndex = uri.indexOf(":", atIndex + 1);
            if (colonIndex != -1 && colonIndex < slashIndex) {
                hostName = uri.substring(atIndex + 1, colonIndex);
                try {
                    hostPort = new Integer(uri.substring(colonIndex + 1, slashIndex));
                } catch (NumberFormatException excp) {
                    hostPort = -1;
                    throw new URISyntaxException(uri, "Invalid Host port given in URI");
                }
            }
            else {
                hostName = uri.substring(atIndex + 1, slashIndex);
                hostPort = -1;
            }

        }

        /* Finally, take everything past the slash as the asset path */
        assetPath = uri.substring(slashIndex + 1, uri.length());
    }

    /**
     * Parse the a server name and port as <host name>:<port> into its parts
     */
    private void parseHostNameAndPort(String hostNameAndPort) {
        /* Sanity check: see if the argument is null */
        if (hostNameAndPort == null) {
            this.hostName = null;
            this.hostPort = -1;
            return;
        }

        /* Check if there is a colon (:), if so, parse both host and port */
        int colonIndex = hostNameAndPort.indexOf(":");
        if (colonIndex != -1) {
            this.hostName = hostNameAndPort.substring(0, colonIndex);
            try {
                this.hostPort = new Integer(hostNameAndPort.substring(colonIndex + 1, hostNameAndPort.length()));
            } catch (NumberFormatException excp) {
                this.hostPort = -1;
            }
        }
        else {
            this.hostName = hostNameAndPort;
            this.hostPort = -1;
        }
    }
   
    /**
     * Returns the relative path of the resource specified by the URI within
     * the module. The relative path does not being with any forward "/". This
     * method adds any directories before the relative asset path. This method
     * should return all forward-slashes.
     *
     * @return The relative path within the URI
     */
    public abstract String getRelativePathInModule();
   
    /**
     * Returns a relative path of the asset so that it exists in a unique
     * location within a cache. The path does not have a leading "/".
     *
     * @return A unique relative path for the URI
     */
    public String getRelativeCachePath() {
        return "module" + File.separator + this.getModuleName() + File.separator + this.getRelativePathInModule();
    }
}
TOP

Related Classes of org.jdesktop.wonderland.common.ModuleURI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.