001    /*
002     * Apache License
003     * Version 2.0, January 2004
004     * http://www.apache.org/licenses/
005     *
006     * Copyright 1996-2008 by Sven Homburg
007     *
008     * Licensed under the Apache License, Version 2.0 (the "License");
009     * you may not use this file except in compliance with the License.
010     * You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     */
014    
015    package org.chenillekit.core.resources;
016    
017    import java.io.File;
018    import java.io.IOException;
019    import java.io.InputStream;
020    import java.net.MalformedURLException;
021    import java.net.URI;
022    import java.net.URISyntaxException;
023    import java.net.URL;
024    import java.util.Locale;
025    
026    import org.apache.tapestry5.ioc.Resource;
027    import org.apache.tapestry5.ioc.internal.util.LocalizedNameGenerator;
028    
029    /**
030     * A resource stored with in any location (local, remote or jar archive).
031     *
032     * @version $Id: URIResource.java 594 2009-12-05 15:17:26Z mlusetti $
033     */
034    public class URIResource implements Resource
035    {
036            private URI uri;
037    
038            public URIResource(String uri)
039            {
040                    try
041                    {
042                            this.uri = new URI(uri);
043                    }
044                    catch (URISyntaxException e)
045                    {
046                            throw new RuntimeException(e);
047                    }
048            }
049    
050            public URIResource(URI uri) throws MalformedURLException
051            {
052                    this.uri = uri;
053            }
054    
055            public URIResource(File file) throws MalformedURLException
056            {
057                    this(file.toURI());
058            }
059    
060            public URIResource(URL url) throws URISyntaxException, MalformedURLException
061            {
062                    this(url.toURI());
063            }
064    
065            protected Resource newResource(String uri)
066            {
067                    return new URIResource(uri);
068            }
069    
070            /**
071             * Returns true if the resource exists; if a stream to the content of the file may be openned.
072             *
073             * @return true if the resource exists, false if it does not
074             */
075            public boolean exists()
076            {
077                    InputStream is = null;
078    
079                    try
080                    {
081                            is = uri.toURL().openStream();
082                            int i = is.read();
083                            return true;
084                    }
085                    catch (Exception e)
086                    {
087                            return false;
088                    }
089                    finally
090                    {
091                            try
092                            {
093                                    if (is != null)
094                                            is.close();
095                            }
096                            catch (Exception e)
097                            {
098                                    // do nothing
099                            }
100                    }
101            }
102    
103            /**
104             * Opens a stream to the content of the resource, or returns null if the resource does not exist.
105             *
106             * @return an open, buffered stream to the content, if available
107             */
108            public InputStream openStream() throws IOException
109            {
110                    return uri.toURL().openStream();
111            }
112    
113            /**
114             * Returns the URL for the resource, or null if it does not exist.
115             */
116            public URL toURL()
117            {
118                    try
119                    {
120                            if (exists())
121                                    return uri.toURL();
122                    }
123                    catch (Exception e)
124                    {
125                            // do nothing
126                    }
127    
128                    return null;
129            }
130    
131            /**
132             * Returns a localized version of the resource. May return null if no such resource exists.
133             */
134            public Resource forLocale(Locale locale)
135            {
136                    for (String path : new LocalizedNameGenerator(this.uri.toString(), locale))
137                    {
138                            Resource potential = createResource(path);
139    
140                            if (potential.exists()) return potential;
141                    }
142    
143                    return null;
144            }
145    
146            /**
147             * Creates a new resource, unless the path matches the current Resource's path (in which case, this resource is
148             * returned).
149             */
150            private Resource createResource(String path)
151            {
152                    if (this.uri.toString().equals(path)) return this;
153    
154                    return newResource(path);
155            }
156    
157            /**
158             * Returns a Resource based on a relative path, relative to the folder containing the resource. Understands the "."
159             * (current folder) and ".." (parent folder) conventions, and treats multiple sequential slashes as a single slash.
160             */
161            public Resource forFile(String relativePath)
162            {
163                    return createResource(relativePath);
164            }
165    
166            /**
167             * Returns a new Resource with the extension changed (or, if the resource does not have an extension, the extension
168             * is added). The new Resource may not exist (that is, {@link #toURL()} may return null.
169             *
170             * @param extension to apply to the resource, such as "html" or "properties"
171             *
172             * @return the new resource
173             */
174            public Resource withExtension(String extension)
175            {
176                    throw new RuntimeException("not implemented yet!");
177            }
178    
179            /**
180             * Returns the portion of the path up to the last forward slash; this is the directory or folder portion of the
181             * Resource.
182             */
183            public String getFolder()
184            {
185                    String folderName = "";
186                    String completePath = toURL().getPath();
187    
188                    if (completePath != null)
189                    {
190                            int lastSlash = completePath.lastIndexOf('/');
191                            if (lastSlash > 0)
192                                    folderName = completePath.substring(0, lastSlash);
193                    }
194    
195                    return folderName;
196            }
197    
198            /**
199             * Returns the file portion of the Resource path, everything that follows the final forward slash.
200             */
201            public String getFile()
202            {
203                    String fileName = "";
204                    String completePath = toURL().getPath();
205    
206                    if (completePath != null)
207                    {
208                            if (completePath.lastIndexOf('/') > 0)
209                                    fileName = completePath.substring(completePath.lastIndexOf('/') + 1);
210                            else
211                                    fileName = completePath;
212                    }
213    
214                    return fileName;
215            }
216    
217            /**
218             * Return the path (the combination of folder and file).
219             */
220            public String getPath()
221            {
222                    return toURL().toExternalForm();
223            }
224    
225            @Override
226            public boolean equals(Object obj)
227            {
228                    if (obj == null) return false;
229    
230                    if (obj == this) return true;
231    
232                    if (obj.getClass() != getClass()) return false;
233    
234                    URIResource other = (URIResource) obj;
235    
236                    return other.getPath().equals(getPath());
237            }
238    
239            @Override
240            public int hashCode()
241            {
242                    return 227 ^ getPath().hashCode();
243            }
244    
245            @Override
246            public String toString()
247            {
248                    return String.format("uri:%s", uri.toString());
249            }
250    }