blob: e59f0d7245078970f9e3992ca4a7e2fecb31b6c2 [file] [log] [blame]
// Copyright 2006, 2008 The Apache Software Foundation
//
// Licensed 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.tapestry5.ioc.internal.util;
import org.apache.tapestry5.ioc.Resource;
import static org.apache.tapestry5.ioc.internal.util.Defense.notBlank;
import static org.apache.tapestry5.ioc.internal.util.Defense.notNull;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Locale;
/**
* Abstract implementation of {@link Resource}. Subclasses must implement the abstract methods {@link Resource#toURL()}
* and {@link #newResource(String)} as well as toString(), hashCode() and equals().
*/
public abstract class AbstractResource implements Resource
{
private final String path;
protected AbstractResource(String path)
{
this.path = notNull(path, "path");
}
public final String getPath()
{
return path;
}
public final String getFile()
{
int slashx = path.lastIndexOf('/');
return path.substring(slashx + 1);
}
public final String getFolder()
{
int slashx = path.lastIndexOf('/');
return (slashx < 0) ? "" : path.substring(0, slashx);
}
public final Resource forFile(String relativePath)
{
Defense.notNull(relativePath, "relativePath");
StringBuilder builder = new StringBuilder(getFolder());
for (String term : relativePath.split("/"))
{
// This will occur if the relative path contains sequential slashes
if (term.equals("")) continue;
if (term.equals(".")) continue;
if (term.equals(".."))
{
int slashx = builder.lastIndexOf("/");
// TODO: slashx < 0 (i.e., no slash)
// Trim path to content before the slash
builder.setLength(slashx);
continue;
}
// TODO: term blank or otherwise invalid?
// TODO: final term should not be "." or "..", or for that matter, the
// name of a folder, since a Resource should be a file within
// a folder.
if (builder.length() > 0) builder.append("/");
builder.append(term);
}
return createResource(builder.toString());
}
public final Resource forLocale(Locale locale)
{
for (String path : new LocalizedNameGenerator(this.path, locale))
{
Resource potential = createResource(path);
if (potential.exists()) return potential;
}
return null;
}
public final Resource withExtension(String extension)
{
notBlank(extension, "extension");
int dotx = path.lastIndexOf('.');
if (dotx < 0) return createResource(path + "." + extension);
return createResource(path.substring(0, dotx + 1) + extension);
}
/**
* Creates a new resource, unless the path matches the current Resource's path (in which case, this resource is
* returned).
*/
private Resource createResource(String path)
{
if (this.path.equals(path)) return this;
return newResource(path);
}
/**
* Simple check for whether {@link #toURL()} returns null or not.
*/
public boolean exists()
{
return toURL() != null;
}
/**
* Obtains the URL for the Resource and opens the stream, wrapped by a BufferedInputStream.
*/
public InputStream openStream() throws IOException
{
URL url = toURL();
if (url == null) return null;
return new BufferedInputStream(url.openStream());
}
/**
* Factory method provided by subclasses.
*/
protected abstract Resource newResource(String path);
}