001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.util.resource;
018
019import java.io.FileInputStream;
020import java.io.FileNotFoundException;
021import java.io.IOException;
022import java.io.InputStream;
023import java.net.URLConnection;
024import java.time.Instant;
025import org.apache.wicket.util.file.File;
026import org.apache.wicket.util.lang.Args;
027import org.apache.wicket.util.lang.Bytes;
028
029
030/**
031 * A FileResourceStream is an IResource implementation for files.
032 * 
033 * @see org.apache.wicket.util.resource.IResourceStream
034 * @see org.apache.wicket.util.watch.IModifiable
035 * @author Jonathan Locke
036 */
037public class FileResourceStream extends AbstractResourceStream
038        implements
039                IFixedLocationResourceStream
040{
041        private static final long serialVersionUID = 1L;
042
043        /** Any associated file */
044        private final File file;
045
046        /** Resource stream */
047        private transient InputStream inputStream;
048
049        /**
050         * Constructor.
051         * 
052         * @param file
053         *            {@link File} containing resource
054         */
055        public FileResourceStream(final File file)
056        {
057                Args.notNull(file, "file");
058                this.file = file;
059        }
060
061        /**
062         * Constructor.
063         * 
064         * @param file
065         *            {@link java.io.File} containing resource
066         */
067        public FileResourceStream(final java.io.File file)
068        {
069                this.file = new File(file);
070        }
071
072        /**
073         * Closes this resource.
074         * 
075         * @throws IOException
076         */
077        @Override
078        public void close() throws IOException
079        {
080                if (inputStream != null)
081                {
082                        inputStream.close();
083                        inputStream = null;
084                }
085        }
086
087        @Override
088        public String getContentType()
089        {
090                String contentType = null;
091                if (file != null)
092                {
093                        contentType = URLConnection.getFileNameMap().getContentTypeFor(file.getName());
094                }
095                return contentType;
096        }
097
098        /**
099         * @return The file this resource resides in, if any.
100         */
101        public File getFile()
102        {
103                return file;
104        }
105
106        /**
107         * @return A readable input stream for this resource. The same input stream is returned until
108         *         <tt>FileResourceStream.close()</tt> is invoked.
109         * 
110         * @throws ResourceStreamNotFoundException
111         */
112        @Override
113        public InputStream getInputStream() throws ResourceStreamNotFoundException
114        {
115                if (inputStream == null)
116                {
117                        try
118                        {
119                                inputStream = new FileInputStream(file);
120                        }
121                        catch (FileNotFoundException e)
122                        {
123                                throw new ResourceStreamNotFoundException("Resource " + file +
124                                        " could not be found", e);
125                        }
126                }
127
128                return inputStream;
129        }
130
131        /**
132         * @see org.apache.wicket.util.watch.IModifiable#lastModifiedTime()
133         * @return The last time this resource was modified
134         */
135        @Override
136        public Instant lastModifiedTime()
137        {
138                if (file != null)
139                {
140                        return file.lastModifiedTime();
141                }
142                return null;
143        }
144
145        @Override
146        public String toString()
147        {
148                if (file != null)
149                {
150                        return file.toString();
151                }
152                return "";
153        }
154
155        @Override
156        public Bytes length()
157        {
158                if (file != null)
159                {
160                        return Bytes.bytes(file.length());
161                }
162                return null;
163        }
164
165        @Override
166        public String locationAsString()
167        {
168                if (file != null)
169                {
170                        return file.getAbsolutePath();
171                }
172                return null;
173        }
174}