All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.catalina.webresources.StandardRoot Maven / Gradle / Ivy

There is a newer version: 11.0.0-M26
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.catalina.webresources;

import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.WebResourceSet;
import org.apache.catalina.util.LifecycleMBeanBase;
import org.apache.tomcat.util.res.StringManager;

/**
 * 

* Provides the resources implementation for a web application. The * {@link org.apache.catalina.Lifecycle} of this class should be aligned with * that of the associated {@link Context}. *

* This implementation assumes that the base attribute supplied to {@link * StandardRoot#createWebResourceSet( * org.apache.catalina.WebResourceRoot.ResourceSetType, String, String, String)} * represents the absolute path to a file. *

*/ public class StandardRoot extends LifecycleMBeanBase implements WebResourceRoot { protected static final StringManager sm = StringManager.getManager(Constants.Package); private Context context; private boolean allowLinking = false; private ArrayList preResources = new ArrayList<>(); private WebResourceSet main; private ArrayList jarResources = new ArrayList<>(); private ArrayList postResources = new ArrayList<>(); private Cache cache = new Cache(this); private boolean cachingAllowed = true; // Constructs to make iteration over all WebResourceSets simpler private ArrayList mainResources = new ArrayList<>(); private ArrayList> allResources = new ArrayList<>(); { allResources.add(preResources); allResources.add(mainResources); allResources.add(jarResources); allResources.add(postResources); } /** * Creates a new standard implementation of {@link WebResourceRoot}. A no * argument constructor is required for this to work with the digester. * {@link #setContext(Context)} must be called before this component is * initialized. */ public StandardRoot() { // NO-OP } public StandardRoot(Context context) { this.context = context; } @Override public String[] list(String path) { checkState(); // Set because we don't want duplicates HashSet result = new HashSet<>(); for (ArrayList list : allResources) { for (WebResourceSet webResourceSet : list) { String[] entries = webResourceSet.list(path); for (String entry : entries) { result.add(entry); } } } return result.toArray(new String[result.size()]); } @Override public Set listWebAppPaths(String path) { checkState(); // Set because we don't want duplicates HashSet result = new HashSet<>(); for (ArrayList list : allResources) { for (WebResourceSet webResourceSet : list) { result.addAll(webResourceSet.listWebAppPaths(path)); } } if (result.size() == 0) { return null; } return result; } @Override public boolean mkdir(String path) { checkState(); if (preResourceExists(path)) { return false; } return main.mkdir(path); } @Override public boolean write(String path, InputStream is, boolean overwrite) { checkState(); if (!overwrite && preResourceExists(path)) { return false; } return main.write(path, is, overwrite); } private boolean preResourceExists(String path) { for (WebResourceSet webResourceSet : preResources) { WebResource webResource = webResourceSet.getResource(path); if (webResource.exists()) { return true; } } return false; } @Override public WebResource getResource(String path) { if (isCachingAllowed()) { return cache.getResource(path); } else { return getResourceInternal(path); } } protected WebResource getResourceInternal(String path) { checkState(); WebResource result = null; WebResource virtual = null; for (ArrayList list : allResources) { for (WebResourceSet webResourceSet : list) { result = webResourceSet.getResource(path); if (result.exists()) { return result; } if (virtual == null && result.isVirtual()) { virtual = result; } } } // Use the first virtual result if no real result was found if (virtual != null) { return virtual; } // Default is empty resource in main resources return new EmptyResource(this, path); } @Override public WebResource[] getResources(String path) { checkState(); ArrayList result = new ArrayList<>(); for (ArrayList list : allResources) { for (WebResourceSet webResourceSet : list) { WebResource webResource = webResourceSet.getResource(path); if (webResource.exists()) { result.add(webResource); } } } if (result.size() == 0) { result.add(main.getResource(path)); } return result.toArray(new WebResource[result.size()]); } @Override public WebResource[] listResources(String path) { checkState(); String[] resources = list(path); WebResource[] result = new WebResource[resources.length]; for (int i = 0; i < resources.length; i++) { if (path.charAt(path.length() - 1) == '/') { result[i] = getResource(path + resources[i]); } else { result[i] = getResource(path + '/' + resources[i]); } } return result; } @Override public void createWebResourceSet(ResourceSetType type, URL url, String webAppMount, String internalPath) { createWebResourceSet(type, toBase(url), webAppMount, internalPath); } @Override public void createWebResourceSet(ResourceSetType type, String base, String webAppMount, String internalPath) { ArrayList resourceList; WebResourceSet resourceSet; switch (type) { case PRE: resourceList = preResources; break; case RESOURCE_JAR: resourceList = jarResources; break; case POST: resourceList = postResources; break; default: throw new IllegalArgumentException( sm.getString("standardRoot.createUnknownType", type)); } // This implementation assumes that the base for all resources will be a // file. File file = new File(base); if (file.isFile()) { if (file.getName().toLowerCase(Locale.ENGLISH).endsWith(".jar")) { resourceSet = new JarResourceSet(this, base, webAppMount, internalPath); } else { resourceSet = new FileResourceSet(this, base, webAppMount, internalPath); } } else if (file.isDirectory()) { resourceSet = new DirResourceSet(this, base, webAppMount, internalPath); } else { throw new IllegalArgumentException( sm.getString("standardRoot.createInvalidFile", file)); } resourceList.add(resourceSet); } @Override public void addPreResources(WebResourceSet webResourceSet) { webResourceSet.setRoot(this); preResources.add(webResourceSet); } @Override public WebResourceSet[] getPreResources() { return preResources.toArray(new WebResourceSet[0]); } @Override public void addJarResources(WebResourceSet webResourceSet) { webResourceSet.setRoot(this); jarResources.add(webResourceSet); } @Override public WebResourceSet[] getJarResources() { return jarResources.toArray(new WebResourceSet[0]); } @Override public void addPostResources(WebResourceSet webResourceSet) { webResourceSet.setRoot(this); postResources.add(webResourceSet); } @Override public WebResourceSet[] getPostResources() { return postResources.toArray(new WebResourceSet[0]); } @Override public void setAllowLinking(boolean allowLinking) { this.allowLinking = allowLinking; } @Override public boolean getAllowLinking() { return allowLinking; } @Override public void setCachingAllowed(boolean cachingAllowed) { this.cachingAllowed = cachingAllowed; } @Override public boolean isCachingAllowed() { return cachingAllowed; } @Override public long getCacheTtl() { return cache.getTtl(); } @Override public void setCacheTtl(long cacheTtl) { cache.setTtl(cacheTtl); } @Override public long getCacheMaxSize() { return cache.getMaxSize(); } @Override public void setCacheMaxSize(long cacheMaxSize) { cache.setMaxSize(cacheMaxSize); } @Override public void setCacheMaxObjectSize(long cacheMaxObjectSize) { cache.setMaxObjectSize(cacheMaxObjectSize); } @Override public long getCacheMaxObjectSize() { return cache.getMaxObjectSize(); } @Override public Context getContext() { return context; } @Override public void setContext(Context context) { this.context = context; } private void checkState() { if (!getState().isAvailable()) { throw new IllegalStateException( sm.getString("standardRoot.checkStateNotStarted")); } } protected String toBase(URL url) { File f = null; if ("jar".equals(url.getProtocol())) { String jarUrl = url.toString(); String fileUrl = jarUrl.substring(4, jarUrl.length() - 2); try { f = new File(new URL(fileUrl).toURI()); } catch (MalformedURLException | URISyntaxException e) { throw new IllegalArgumentException(e); } } else { try { f = new File(url.toURI()); } catch (URISyntaxException e) { throw new IllegalArgumentException(e); } } return f.getAbsolutePath(); } /** * For unit testing */ protected void setMainResources(WebResourceSet main) { this.main = main; mainResources.clear(); mainResources.add(main); } @Override public void backgroundProcess() { cache.backgroundProcess(); } // ----------------------------------------------------------- JMX Lifecycle @Override protected String getDomainInternal() { return context.getDomain(); } @Override protected String getObjectNameKeyProperties() { StringBuilder keyProperties = new StringBuilder("type=WebResourceRoot"); keyProperties.append(context.getMBeanKeyProperties()); return keyProperties.toString(); } // --------------------------------------------------------------- Lifecycle @Override protected void initInternal() throws LifecycleException { super.initInternal(); if (context == null) { throw new IllegalStateException( sm.getString("standardRoot.noContext")); } for (ArrayList list : allResources) { for (WebResourceSet webResourceSet : list) { webResourceSet.init(); } } } @Override protected void startInternal() throws LifecycleException { String docBase = context.getDocBase(); File f = new File(docBase); if (!f.isAbsolute()) { f = new File(((Host)context.getParent()).getAppBaseFile(), f.getName()); } if (f.isDirectory()) { main = new DirResourceSet(this, f.getAbsolutePath(), "/", "/"); } else if(f.isFile() && docBase.endsWith(".war")) { main = new JarResourceSet(this, f.getAbsolutePath(), "/", "/"); } else { throw new IllegalArgumentException( sm.getString("standardRoot.startInvalidMain", f.getAbsolutePath())); } mainResources.clear(); mainResources.add(main); for (ArrayList list : allResources) { for (WebResourceSet webResourceSet : list) { webResourceSet.start(); } } setState(LifecycleState.STARTING); } @Override protected void stopInternal() throws LifecycleException { for (ArrayList list : allResources) { for (WebResourceSet webResourceSet : list) { webResourceSet.stop(); } } if (main != null) { main.destroy(); } mainResources.clear(); for (WebResourceSet webResourceSet : jarResources) { webResourceSet.destroy(); } jarResources.clear(); setState(LifecycleState.STOPPING); } @Override protected void destroyInternal() throws LifecycleException { for (ArrayList list : allResources) { for (WebResourceSet webResourceSet : list) { webResourceSet.destroy(); } } super.destroyInternal(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy