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.core.util.resource; 018 019import java.io.FileNotFoundException; 020import java.io.IOException; 021import java.io.InputStream; 022import java.net.URL; 023import java.time.Instant; 024import jakarta.servlet.ServletContext; 025import org.apache.wicket.Application; 026import org.apache.wicket.protocol.http.WebApplication; 027import org.apache.wicket.util.io.Connections; 028import org.apache.wicket.util.io.IOUtils; 029import org.apache.wicket.util.lang.Bytes; 030import org.apache.wicket.util.resource.AbstractResourceStream; 031import org.apache.wicket.util.resource.ResourceStreamNotFoundException; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035/** 036 * An {@link org.apache.wicket.util.resource.IResourceStream} that reads data from a file in the web application 037 * 038 * @author <a href="mailto:jbq@apache.org">Jean-Baptiste Quenot</a> 039 */ 040public class WebExternalResourceStream extends AbstractResourceStream 041{ 042 private static final Logger log = LoggerFactory.getLogger(WebExternalResourceStream.class); 043 private static final long serialVersionUID = 1L; 044 045 transient InputStream in; 046 047 /** the relative url of the external resource. */ 048 private final String url; 049 050 /** 051 * Construct. 052 * 053 * @param url 054 * the relative url of the external resource 055 */ 056 public WebExternalResourceStream(String url) 057 { 058 if (url == null) 059 { 060 throw new IllegalArgumentException("Argument url must be not null"); 061 } 062 063 this.url = url; 064 } 065 066 @Override 067 public Bytes length() 068 { 069 return null; 070 } 071 072 @Override 073 public void close() throws IOException 074 { 075 // getInputStream() is not always called (WICKET-790) 076 IOUtils.close(in); 077 } 078 079 @Override 080 public Instant lastModifiedTime() 081 { 082 try 083 { 084 final ServletContext context = ((WebApplication)Application.get()).getServletContext(); 085 final URL resourceURL = context.getResource(url); 086 if (resourceURL == null) 087 { 088 throw new FileNotFoundException("Unable to find resource '" + url + 089 "' in the servlet context"); 090 } 091 092 return Connections.getLastModified(resourceURL); 093 } 094 catch (IOException e) 095 { 096 log.warn("failed to retrieve last modified timestamp", e); 097 return null; 098 } 099 } 100 101 @Override 102 public String getContentType() 103 { 104 return WebApplication.get().getServletContext().getMimeType(url); 105 } 106 107 @Override 108 public InputStream getInputStream() throws ResourceStreamNotFoundException 109 { 110 final ServletContext context = ((WebApplication)Application.get()).getServletContext(); 111 112 in = context.getResourceAsStream(url); 113 if (in == null) 114 { 115 throw new ResourceStreamNotFoundException("The requested resource was not found: " + 116 url); 117 } 118 return in; 119 } 120}