001: /*
002: * IndexedComponent.java February 2001
003: *
004: * Copyright (C) 2001, Niall Gallagher <niallg@users.sf.net>
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General
016: * Public License along with this library; if not, write to the
017: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
018: * Boston, MA 02111-1307 USA
019: */
020:
021: package simple.http.serve;
022:
023: import simple.util.net.Path;
024: import java.io.FileInputStream;
025: import java.io.IOException;
026: import java.io.InputStream;
027: import java.util.Locale;
028: import java.io.File;
029:
030: /**
031: * The <code>IndexedComponent</code> is used to provide any specific
032: * meta data for any file based <code>Component</code>s. This provides
033: * methods that allow the <code>Component</code> to be indexed by the
034: * <code>Context</code> object, this allows the server to build meta
035: * information on a resource without having to refer to a centralized
036: * table that matches the resource with its meta information.
037: * <p>
038: * Such approaches are used with servers like Apache that can have
039: * information stored in a file to describe the Language, Type etc.
040: * of a resource. This however uses a scheme that discovers the meta
041: * information of the <code>Component</code> by parsing the request URI.
042: * The <code>File</code>s that are indexed can have locale extensions
043: * to that the <code>Component</code>s can be discriminated upon based
044: * on preferred Language.
045: *
046: * @author Niall Gallagher
047: */
048: abstract class IndexedComponent extends Component {
049:
050: /**
051: * This is the HTTP URI that references this resource.
052: */
053: protected String target;
054:
055: /**
056: * This is the index that contains all the meta data.
057: */
058: protected Index index;
059:
060: /**
061: * Creates a default indexed object that is indexed based on
062: * the path name that it is given. The <code>Context</code> is
063: * used to parse the path and set the meta data. The meta data
064: * of the <code>Component</code> is set based on a set of rules
065: * specified by the <code>Context</code>. The path is broken
066: * into its separate components like its name, type, path etc.
067: * This will create the <code>Component</code> relative to the
068: * specified directory. i.e. the <code>Component</code> is
069: * created from a file that is rooted at the base directory.
070: *
071: * @param context the context that this resource is relative to
072: * @param target this is the HTTP request URI this represents
073: */
074: protected IndexedComponent(Context context, String target) {
075: this .index = context.getIndex(target);
076: this .context = context;
077: this .target = target;
078: }
079:
080: /**
081: * This allows the name for this object to be acquired. The
082: * name usually refers to the last entry in the path. So if
083: * the index target path was "/usr/bin/" the name is "bin".
084: *
085: * @return this returns the name of this index target
086: */
087: public String getName() {
088: return index.getName();
089: }
090:
091: /**
092: * This allows the MIME type of this <code>Index</code> to
093: * be acquired. The MIME type of a file is retrieved by the
094: * <code>Context.getContentType</code> method for a specific
095: * request URI. This should have a value and perhaps some
096: * parameters like the charset, "text/html; charset=UTF-8".
097: *
098: * @return the MIME type this object has been set to
099: */
100: public String getContentType() {
101: return index.getContentType();
102: }
103:
104: /**
105: * This gets the locale for this index object the locale is
106: * set to the <code>Locale.getDefault</code> if there is no
107: * locale information available for the index target. This
108: * will provide the <code>Context.getLocale</code> object.
109: *
110: * @return this returns the locale for this index target
111: */
112: public Locale getLocale() {
113: return index.getLocale();
114: }
115:
116: /**
117: * This is used to get the path that this object refers to.
118: * This should be the fully qualified normalized path. This
119: * refers to the OS system specific path that this represents.
120: *
121: * @return this returns the OS specific path for the target
122: */
123: public String getRealPath() {
124: return index.getRealPath();
125: }
126:
127: /**
128: * This is used to acquire the normalized URI style path for
129: * the index target. This allows the path to be used within
130: * the <code>Mapper</code> and other such objects that need
131: * a normalized URI style path to resolve resources.
132: *
133: * @return this returns the normalized path for the target
134: */
135: public String getRequestPath() {
136: return index.getRequestPath();
137: }
138:
139: /**
140: * This is used to acquire the <code>File</code> directory
141: * for the index target. This is typically rooted at a
142: * base path, for instance the <code>Context</code> root
143: * is typically used. This allows resources within the
144: * same directory to be acquired easily.
145: *
146: * @return this returns the OS file for the directory
147: */
148: public File getDirectory() {
149: return index.getDirectory();
150: }
151:
152: /**
153: * This is used to acquire the <code>File</code> reference
154: * for the index target. This is typically rooted at a
155: * base path, for instance the <code>Context</code> root
156: * is typically used. This allows the file to be opened,
157: * deleted, or read should the need arise in a service.
158: *
159: * @return this returns the OS file for the resource
160: */
161: public File getFile() {
162: return index.getFile();
163: }
164:
165: /**
166: * This is used to acquire the <code>Path</code> object that
167: * exposes various parts of the URI path. This can be used
168: * to extract the individual path segments as strings as
169: * well as the file extension and various other details.
170: *
171: * @return this returns a path object with various details
172: */
173: public Path getPath() {
174: return index.getPath();
175: }
176:
177: /**
178: * This is a simple convienience method that enables subclasses
179: * to retrieve the <code>FileInputStream</code> for the file.
180: *
181: * @return this returns the <code>FileInputStream</code> that
182: * represents the targeted file
183: *
184: * @throws IOException thrown if the file does not exist
185: */
186: protected InputStream getInputStream() throws IOException {
187: return new FileInputStream(getFile());
188: }
189:
190: /**
191: * This returns the date of the last modification of the file.
192: * This date is returned as the long, this is the number of
193: * milliseconds since January 1 1970. This is equivelant to
194: * using the <code>File.lastModified</code> method.
195: *
196: * @return the date of the last modification of the file
197: */
198: protected long getLastModified() {
199: return getFile().lastModified();
200: }
201:
202: /**
203: * This method is used to retrieve the length of the file that
204: * this <code>Content</code> represents. The size of the file
205: * is assumed not to be larger than the maximum integer value,
206: * if it is possible for the length to exceed this length the
207: * <code>File.length</code> method should be used.
208: *
209: * @return this returns the length of the file as an integer
210: */
211: protected int getLength() {
212: return (int) getFile().length();
213: }
214: }
|